.Net attribute

attribute, 用來為 class, method, parameters 貼上標籤,以便後續的應用.
所有的 attribute class 都要繼承 System.Attribute

class Class1Attribute: System.Attribute
{
}

使用的時候可以省略 Attribute

[Class1]
class Class2
{
}

打全名當然也是可以

[Class1Attribute]
class Class2
{
}

使用 xxx( yyy ) 時,attribute 的 constructor 會被套用,而 attribute class 裡的 property 會被自動認定為 named parameter.

class Class1Attribute: System.Attribute
{
private int _id;
private string _name;
public Class1Attribute( int id )
{
_id = id;
}
public string Name
{
get { return _name };
set { _name = value };
}
}
[Class1( 1, Name="This is a test" )]
class class2
{
}

也可以貼很多標籤上去

[AttributeUsage(AttributeTargets.Class, AllowMultiple=true)]
class Class1Attribute: System.Attribute
{
....
}
[Class1( 1, Name="This is a test" ), Class1( 2, Name="Test2" )]
class class2
{
}

但是要怎麼應用呢? 從 .Net framework documentation 裡的 sample, 大致上可以猜到.

using System;
using System.Reflection;
namespace CustomAttrCS {
// An enumeration of animals. Start at 1 (0 = uninitialized).
public enum Animal {
// Pets.
Dog = 1,
Cat,
Bird,
}
// A custom attribute to allow a target to have a pet.
public class AnimalTypeAttribute : Attribute {
// The constructor is called when the attribute is set.
public AnimalTypeAttribute(Animal pet) {
thePet = pet;
}
// Keep a variable internally ...
protected Animal thePet;
// .. and show a copy to the outside world.
public Animal Pet {
get { return thePet; }
set { thePet = Pet; }
}
}
// A test class where each method has its own pet.
class AnimalTypeTestClass {
[AnimalType(Animal.Dog)]
public void DogMethod() {}
[AnimalType(Animal.Cat)]
public void CatMethod() {}
[AnimalType(Animal.Bird)]
public void BirdMethod() {}
}
class DemoClass {
static void Main(string[] args) {
AnimalTypeTestClass testClass = new AnimalTypeTestClass();
Type type = testClass.GetType();
// Iterate through all the methods of the class.
foreach(MethodInfo mInfo in type.GetMethods()) {
// Iterate through all the Attributes for each method.
foreach (Attribute attr in Attribute.GetCustomAttributes(mInfo)) {
// Check for the AnimalType attribute.
if (attr.GetType() == typeof(AnimalTypeAttribute))
Console.WriteLine(
"Method {0} has a pet {1} attribute.",
mInfo.Name, ((AnimalTypeAttribute)attr).Pet);
}
}
}
}
}

所以你可以看到,在貼上標籤以後,其實對 Class 本身來說沒啥作用,會認為有用的,是其他的 Class, 他們可以依據這些 Attribute 來作一些特定的處理.
這邊有一系列的文章,還提出了應用.

系列 2~4 介紹一個 sql generator 的範例.
系列 5~6 是一個比較深的範例,牽涉到 Remoting 的東西
.Net framework 內也預定了不少 Attribute,我覺得還蠻有用的.
例如: Conditional attribute
以下面的範例來說,如果 DEBUG 沒被定義,那麼 Class1.M() 將不會被執行.
這倒是一個不錯的debug方法

#define DEBUG
using System;
using System.Diagnostics;
class Class1
{
[Conditional("DEBUG")]
public static void M() {
Console.WriteLine("Executed Class1.M");
}
}
class Class2
{
public static void Test() {
Class1.M();
}
}

仔細想想也可以用來作版本控管喔…某版本可以用這個 method, 但是某版本不行….
還有就是 Obsolete, 可以用來指示 class 或 method 即將被淘汰

2005/11/05慶生會

Sharon 的慶生會,當天喝掉兩瓶 Vodka ( 1.5 瓶 absolute vodka + 0.5 的思美樂 )
隔天,我宿醉,吐了,難過了一整天…慘…
好久沒這樣子了.
可是…被老婆念了一頓.
老樣子,還是從Tuboo 的相簿拉到flickr放.
想看全部的相片,請到這裡囉.
60-大合照

[新酷音]ChewingServer無法啟動

公司的電腦老是無法使用新酷音輸入法.
狀況是這樣子的,切換到新酷音輸入法之後,打任何字都會造成短暫的延遲,無法輸入.
大致的猜測,是因為 ChewingServer 無法載入.
利用 svn 下載 source code(包含 library) 之後

svn co https://svn.csie.net/chewing/win32-chewing/
svn co https://svn.csie.net/chewing/libchewing/
svn co https://svn.csie.net/chewing/libchewingpp/

進行 Trace, 花了不到十五分鐘,就找出原因.
答案是因為在載入家目錄下的 hash.dat ( 在 \Document and settings\xxx\application data\chewing\hash.dat)時,發生了異常,導致整個 ChewingServer crash.
這也是為甚麼會有短暫延遲的原因,每輸入一個字,新酷音輸入法就會試著去啟動 ChewingServer,每次啟動,每次都 crash, 因此就會有延遲.
刪除掉 hash.dat, 讓ChewingServer重新產生以後就行了.
這個問題也回報到這裡了…(很遺憾,第一次填寫,搞不清楚甚麼欄位要填啥,不小心把主旨填成自己的名字了,而且回報的內容也不夠好…下次改進)

Architecture

翻閱A UML Pattern Language的時候看到的,覺得很有道理.摘錄如下:

Architecture is what remains when you cannot take away any more things and still understand the system.
Architecture actually cover 3 similar but different ideas: architecture itself, framework, and toplogy.

ArchitectureTriple

FoxPro over TCP/IP

VFP 雖然可以使用 ODBC/OLEDB 存取自己的 Database, 但是, 基本上,那還是 File base 的方式,所以如果你想使用 TCP/IP 方式來存取資料庫,那麼你就得被迫使用其他的 Database,如 Microsoft SQL server, Firebird, Oracle… 之類的.
我的 idea 大致就像這樣子…
FoxProOverTCPIP
裡面的 Custom ODBC Driver 與 Daemon/Service 就是要寫的部份.
本想找找看,要怎麼寫 ODBC driver 的.
結果不小心發現,已經有人寫了類似的東西了.
一個是 ODBC Socket Server,另外一個則是Open Database Transport Protocol),都跟我的 idea 相當類似.
ODBC Socket Server, 主要是 client 提供 connect string 與 query string, 讓 server 去做 query 的動作並傳回 xml.
這裡有一些可以參考的文章:
*ODBC Socket Server, PHPBuilder.com
Open Database Transport Protocol)的話,跟 PHP 比較相近,所以提供的範例都是 PHP.
嗯嗯,看來是不用多此一舉再寫一次了… 🙂