2012-01-25 367 views
3

我經常使用委託(Actions,WaitCallbacks,Funcs),但我試圖更好地理解它們是什麼。代表究竟是什麼?

我對對象和引用類型等有相當好的理解,以及它們存儲在堆對堆棧的位置?

基本上 - 我試圖從性能的角度來理解代表。有沒有人有任何資源鏈接或可能是一個很好的解釋?

此外 - 什麼是「事件」?他們如何與代表聯繫?他們基本上只是一個迭代的代表名單嗎?

+0

可能重複的[有人可以提煉出適當的英文代表是什麼?](http://stackoverflow.com/questions/2541683/can-someone-distill-into-proper-english-what-a-delegate-是) – Lucero

+0

就這麼你知道,堆棧vs堆的東西是一個實現細節 - 並且是一個誤導性過度簡化的東西。堆可以存儲堆棧可以存儲的任何東西,否則你的對象內不能有'int'字段。 – cHao

+0

'ildasm'將回答你所有的問題 –

回答

2

到目前爲止所說的一切都是正確的。下面是它是如何工作的:一個委託有兩個字段:一個指向可執行代碼的指針和一個表示這個參數的類型對象字段(你可以將委託委託給一個實例方法)。

當你調用這個委託時,CPU會將指向代碼的指針提取到一個寄存器中,然後「調用」這個指針。調用指令不需要使用常量值。 CPU可以跳轉到內存中的一個可變位置。

事件只是委託加兩個包裝方法來附加一個新的委託或刪除一個現有的。令人困惑的部分是,代表們有第三個領域我離開了:代表!代表組成一個鏈表。這被稱爲MulticastDelegate,它是一種可憎的東西。當您調用委託時,它可能會導致多個具有相同簽名的方法被調用。這是事件的工作方式。事件是委託類型的單個字段。

現在忘記了多播委託,因爲它們在實踐中並不相關。

+0

所以當你說'CPU可以跳到內存中的一個可變位置'時,你是在談論堆棧還是堆?事件如何適應所有這些? – William

+0

我爲事件添加了一段。我不明白「堆棧或堆」的含義。這與代表有什麼關係? CPU不會跳轉到數據(在堆棧或堆上)。它跳轉到位於運行時內部代碼堆上的Jitted代碼。代碼只是內存中的字節。 – usr

+0

也許你誤讀了「可變位置」。這與變量無關。該位置本身是可變的,它不能靜態確定。它是一個指針。 – usr

0

代表是代表函數的數據結構 - 返回類型和參數(類型和數字)。任何匹配委託返回類型和簽名的方法都可以分配給這樣的委託。

在性能方面 - 這是一個額外的抽象層,但是很小。這不是你可能會注意到的。

0

代表可以有兩種類型,從我的理解:

  • 「實例綁定的方法指針」,這意味着該委託包含訂閱對象的對象實例,並在對象的方法類來調用。如果我有MyClass.Handler(),並創建了五個MyClass實例,併爲每個實例創建5個委託,並指向Handler()方法,則每個委託將具有相同的方法指針,但是具有不同的對象實例。

  • 靜態方法指針,例如對靜態方法的委託,在這種情況下不需要對象上下文。

事件是MulticastDelegate對象,您甚至可以檢查它們以查看誰正在訂閱事件。使用反射,您可以審覈您的事件的訂閱者。

0

委託是允許您引用方法的C#語言元素。如果你是C或C++程序員,這聽起來很熟悉,因爲代表基本上是一個函數指針。但是,使用其他語言的開發人員可能會想知道,「爲什麼我需要對方法的引用?」。答案歸結爲爲您提供最大的靈活性,以便在運行時實現您想要的任何功能。