2011-08-22 36 views
1

我知道委託類型是從繼承自Delegate類的MulticastDelegate繼承的。內部生成委託類型的方法?

另外,當我們創建委託實例時,它會創建三個方法(Invoke,BeginInvoke,EndInvoke與構造函數分開),並使用相同的委託簽名。

我不能理解它是如何在內部創建的(具有委託類型簽名的方法)?

在此先感謝。

+0

它是如何創建的 - 代碼是由C#編譯器發出的。你還需要知道什麼? –

回答

2

比方說,例如,我們有一個委託這樣的:

public delegate int BinaryOp(int x, int y); 

編譯器如何知道如何定義的invoke()的BeginInvoke()和 EndInvoke會()方法?

這是生成的類被編譯器:

sealed class BinaryOp : System.MulticastDelegate 
{ 
public BinaryOp(object target, uint functionAddress); 
public int Invoke(int x, int y); 
public IAsyncResult BeginInvoke(int x, int y,AsyncCallback cb, object state); 
public int EndInvoke(IAsyncResult result); 
} 

首先,請注意,對於調用()方法完全相同 匹配BinaryOp委託的定義中定義的參數和返回值。

BeginInvoke()成員(本例中爲兩個整數)的初始參數也基於BinaryOp委託;但是,BeginInvoke()將始終提供兩個用於促進異步方法調用的最終參數(類型爲AsyncCallback和object)。

最後,EndInvoke()的返回值與原始的 委託聲明完全相同,並將始終作爲實現Ixia接口的對象的唯一參數。

+0

你的意思是說編譯器會照顧用正確的參數生成方法嗎? – Syed

+0

是的。編譯器將查看委託的返回類型和參數,並相應地創建方法。例如,如果char類型的兩個參數在哪裏,則生成的類中的方法將具有char類型的參數。 – 2011-08-22 17:47:20

+0

謝謝,我們在哪裏可以看到這個編譯器生成的代碼? – Syed

4

如果你有反射或ILSpy看一個委託類型的IL,你會看到,它看起來是這樣的:

.class public sealed System.Action extends System.MulticastDelegate 
{ 
    .method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed {} 

    .method public hidebysig newslot virtual instance void Invoke() runtime managed {} 

    .method public hidebysig newslot virtual instance class System.IAsyncResult BeginInvoke(class System.AsyncCallback callback, object 'object') runtime managed {} 

    .method public hidebysig newslot virtual instance void EndInvoke(class System.IAsyncResult result) runtime managed {} 
} 

即構造(.ctorInvoke,和BeginInvoke/EndInvoke方法。您還會注意到這些方法沒有實現(方法體是空的),並且標記爲runtime

runtime關鍵字向CLR指示此方法需要由CLR本身提供的實現。也就是說,在CLR本身內部實現代理完全是Magic。加載委託類型時,CLR注意到它從System.Delegate派生,注意到runtime標誌,因此在CLR內針對該特定委託類型創建這些方法的實現。

這些實現的實際外觀完全取決於您運行它的CLR(無論.NET平臺,Mono還是其他),但可能直接在本機代碼中。

當編譯器編譯委託類型時,它只是簡單地創建這些方法存根以匹配CLR所期望的這種模式,並將其留在那裏。委託實際工作的方式取決於運行時。