1.日補充
近日開始讀園子炒得比較熱的王翔老師的新作,初看第一章內容比較對我口味,委託中還有很多不懂的,順手記了下來。
預備知識
Delegate中的靜態方法
Delegate.CreateDelegate()方法
在一般情況下,我們直接調用委託的建構函式來產生一個委派物件,但有些情況下我們需要使用CreateDelegate()靜態方法來建立一個指定類型的委託執行個體。此方法有多種重載,見下表(摘自MSDN):
名稱 |
說明 |
Delegate.CreateDelegate (Type, MethodInfo) |
建立指定類型的委託以表示指定的靜態方法。 |
Delegate.CreateDelegate (Type, MethodInfo, Boolean) |
使用針對綁定失敗的指定行為,建立用於表示指定靜態方法的指定類型的委託。 |
Delegate.CreateDelegate (Type, Object, MethodInfo) |
使用指定的第一個參數建立指定類型的委託,該委託表示指定的靜態方法或執行個體方法。 |
Delegate.CreateDelegate (Type, Object, String) |
建立指定類型的委託,該委託表示要對指定的類執行個體調用的指定執行個體方法。 |
Delegate.CreateDelegate (Type, Type, String) |
建立指定類型的委託,該委託表示指定類的指定靜態方法。 |
Delegate.CreateDelegate (Type, Object, MethodInfo, Boolean) |
使用指定的第一個參數和針對綁定失敗的指定行為,建立表示指定的靜態方法或執行個體方法的指定類型的委託。 |
Delegate.CreateDelegate (Type, Object, String, Boolean) |
建立指定類型的委託,該委託表示要按指定的大小寫敏感度對指定類執行個體調用的指定執行個體方法。 |
Delegate.CreateDelegate (Type, Type, String, Boolean) |
使用用於指定是否區分大小寫值建立指定類型的委託,該委託表示指定類的指定靜態方法。 |
Delegate.CreateDelegate (Type, Object, String, Boolean, Boolean) |
使用用於指定是否區分大小寫值和針對綁定失敗的指定行為,建立指定類型的委託,該委託表示要對指定類執行個體調用的指定執行個體方法。 |
Delegate.CreateDelegate (Type, Type, String, Boolean, Boolean) |
使用用於指定是否區分大小寫值和針對綁定失敗的指定行為,建立指定類型的委託,該委託表示指定類的指定靜態方法。 |
重點介紹一個下文將要用到的重載:
public static Delegate CreateDelegate (
Type type,
Object target,
string method
)
參數
type: 要建立的委託的 Type。
target: 類執行個體,對其調用method。
method: 委託要表示的執行個體方法的名稱。
傳回值
指定的類型的委託,表示要對指定的類執行個體調用的指定的執行個體方法。
Delegate.Combine()方法
該方法用於將指定的多路廣播(可組合)委託的調用列表串連起來。在內部Combine()方法是重載的+=運算子的內部實現。用+=進行的委託多路調用都將被編譯為對Combine方法的調用。
Combine()方法的兩個重載:
名稱 |
說明 |
Delegate.Combine (Delegate[]) |
將委託數組的調用列表串連在一起。 |
Delegate.Combine (Delegate, Delegate) |
將兩個委託的調用列表串連在一起。 |
下面是來自書中的一個樣本,使用了上述靜態方法。
樣本的情境是委託需要調用的方法有新的重載,作者在書中給出了下面這個近乎最佳的實現方式:
聲明委託及調用重載方法的代碼:
using System;
using System.Collections.Generic;
namespace MarvellousWorks.PracticalPattern.Concept.Delegating
{
public delegate void MemoHandler(int x, int y, IDictionary<string, int> data);
// 對具有重載的多個目標方法Delegate
public class OverloadableDelegateInvoker
{
private MemoHandler handler;
public OverloadableDelegateInvoker()
{
Type type = typeof(MemoHandler);
Delegate d = Delegate.CreateDelegate(type, new C1(), "A");
d = Delegate.Combine(d, Delegate.CreateDelegate(type, new C2(), "S"));
d = Delegate.Combine(d, Delegate.CreateDelegate(type, new C3(), "M"));
handler = (MemoHandler)d;
}
public void Memo(int x, int y, IDictionary<string, int> data)
{
handler(x, y, data);
}
}
}
其中用到的重載的幾個函數所在的類:
// 重載+
public sealed class C1
{
void A(int x, IDictionary<string, int> data) { data["A"] = x; }
void A(int x, int y, IDictionary<string, int> data) { data["A"] = x + y; }
}
// 重載-
public sealed class C2
{
void S(int x, IDictionary<string, int> data) { data["S"] = x; }
void S(int x, int y, IDictionary<string, int> data) { data["S"] = x - y; }
}
// 重載*
public sealed class C3
{
void M(int x, int y, IDictionary<string, int> data) { data["M"] = x * y; }
}
測試上述委託代碼的類(使用VSTS2005):
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MarvellousWorks.PracticalPattern.Concept.Delegating;
namespace MarvellousWorks.PracticalPattern.Concept.Test
{
[TestClass()]
public class OverloadMulticastDelegateInvokerTest
{
[TestMethod]
public void Test()
{
int result = 10;
int expected = result;
OverloadableDelegateInvoker invoker = new OverloadableDelegateInvoker();
IDictionary<string, int> data = new Dictionary<string, int>();
invoker.Memo(1, 2, data);
Assert.AreEqual<int>(1 + 2, data["A"]);
Assert.AreEqual<int>(1 - 2, data["S"]);
Assert.AreEqual<int>(1 * 2, data["M"]);
}
}
}
本文最後一次修改日期:2009-1-16