標籤:

C#的Delegate的小心得

C# 的 Delegate TypeDelegate 是一種函數指針,但與普通的函數指針相比,區別主要有三:1) 一個 delegate object 一次可以搭載多個方法(methods)[譯註1],而不是一次一個。當我們喚起一個搭載了多個方法(methods)的 delegate,所有方法以其「被搭載到 delegate object 的順序」被依次喚起——稍候我們就來看看如何這樣做。2) 一個 delegate object 所搭載的方法(methods)並不需要屬於同一個類別。一個 delegate object 所搭載的所有方法(methods)必須具有相同的原型和形式。然而,這些方法(methods)可以即有 static 也有 non-static,可以由一個或多個不同類別的成員組成。3) 一個 delegate type 的聲明在本質上是創建了一個新的 subtype instance,該 subtype 派生自 .NET library framework 的 abstract base classes Delegate 或 MulticastDelegate,它們提供一組 public methods 用以詢訪 delegate object 或其搭載的方法(methods)聲明 Delegate Type一個 delegate type 的聲明一般由四部分組成:(a) 訪問級別;(b) 關鍵字 delegate;(c)返回型別,以及該 delegate type 所搭載之方法的聲明形式(signature);(d) delegate type 的名稱,被放置於返回型別和方法的聲明形式(signature)之間。(以上摘自網上)C#雖然取消了指針的這個概念,但還是可以使用指針的,只要聲明這段代碼是非安全的(Unsafe).C#為指針找到一個更為有用的引用類型----代表元,它在C#類型里是十分安全的.在聲明代表元時,只要指定代表元指向的原型的類型,它不能有返回值,也不能帶回輸出類型的參數.代表元可以封裝一個靜態方法,也可以封裝一個非靜態方法.例子如下:例1.

usingSystem;

namespaceDelegate1

{

publicclassMyClass

{

publicintInstanceMethod(inta,intb)

{

Console.WriteLine("CallInstanceMethod");

Console.WriteLine("Firstparametreis{0},secondparametreis{1}",a,b);

return0;

}

staticpublicintStaticMethod()

{

Console.WriteLine("CallStaticMethod");

return0;

}

}

classClass1

{

//聲明的代表元要與將代表的方法的參數序列保持一致

privatedelegateintMyDelegate();

privatedelegateintMeDelegatePara(inta,intb);

[STAThread]

staticvoidMain(string[]args)

{

MyClassp=newMyClass();

//將代表元指向靜態方法StaticMethod

MyDelegateD=newMyDelegate(MyClass.StaticMethod);

D();

//將代表元指向帶參數的非靜態方法InstanceMethod

MeDelegateParad=newMeDelegatePara(p.InstanceMethod);

d(1,2);

}

}

}例1的缺點在於每次使用代表元時都要進行實例化,如果能從類中獲取代表元就方便了很多,解決方法是將代表元的聲明放入到高一級的名字空間中,或者將代表元封裝到一個類中,然後在相關類中以屬性的形式綁定靜態代表.我推薦使用類封裝的方式,下面是改進後的類結構.

usingSystem;

namespaceDelegate1

{

publicclassCDelegate

{

//聲明的代表元與將代表的方法的參數的序列要保持一致

publicdelegateintMyDelegate();

publicdelegateintMeDelegatePara(inta,intb);

}

publicclassMyClass

{

publicintInstanceMethod(inta,intb)

{

Console.WriteLine("CallInstanceMethod");

Console.WriteLine("Firstparametreis{0},secondparametreis{1}",a,b);

return0;

}

staticpublicintStaticMethod()

{

Console.WriteLine("CallStaticMethod");

return0;

}

publicstaticCDelegate.MyDelegateMyDelegate1

{

get

{

returnnewCDelegate.MyDelegate(StaticMethod);

}

}

publicCDelegate.MeDelegateParaMyDelegate2

{

get

{

returnnewCDelegate.MeDelegatePara(InstanceMethod);

}

}

}

classClass1

{

[STAThread]

staticvoidMain(string[]args)

{

MyClassp=newMyClass();

//將代表元指向靜態方法StaticMethod

CDelegate.MyDelegateD=MyClass.MyDelegate1;

D();

//將代表元指向帶參數的非靜態方法InstanceMethod

CDelegate.MeDelegateParad=p.MyDelegate2;

d(1,2);

}

}

}
推薦閱讀:

裝修心得不看後悔 家庭裝修50條注意事項
玄空飛星心得九大要訣B--李居明
教學心得體會
十善心得分享之五十四

TAG:心得 |