對象的普通方法調用與閉包無關;如果您將該方法調用作爲委託進行打包,您只需要關閉!
爲了理解發生了什麼,您需要對「值類型」和「參考類型」的概念有一個很好的把握。淺談Object
在.net中不夠明確,因爲Object
位於層次結構的底部,包括值類型(int
也是Object
)。開始思考純引用類型(如類實例)的方法調用要容易得多。
把你的普通類變量和實例:
List x; // variable declaration
x = new List(); // instantiation
,或者在一行:
List x = new List();
的您的實例的「身體」會留在這就是所謂的堆內存區域。您正在使用的x
僅保留對該內存區域的引用,這就是爲什麼這稱爲reference type
。
當您使用x
變量調用List
上的方法時,該方法需要知道要在哪個列表中工作。因此,該方法簡單地獲取對該實例主體的引用,作爲第一個參數this
參數。說CLR或編譯器傳遞「對象」是不正確的,因爲對象總是在堆上,它只傳遞一個引用(或一個指針)。
當該方法需要調用同一對象的不同方法時,它只是傳遞與第一個參數(它自己接收的第一個參數)相同的this
。
一個正常的方法調用是這樣的:
x.Add(Something); // calls instance method "Add" on "x"
當編譯器看到它知道使用x
作爲this
呼叫到Add
參考(第一個參數,隱藏的一個)。那裏沒有「關閉」!
這裏是一個封閉會是什麼樣子:
List<int> A = new List<int>();
List<int> B = new List<int>();
Action<int> aDelegate; // <-- declare a delegate type variable
// Action<int> is a delegate that returns void and
// takes a single int parameter.
aDelegate = A.Add; // <-- initialize the delegate using an instance method of object A
aDelegate(7); // <- notice the call! No reference to "A" because "A" is already stored in aDelegate
aDelegate = B.Add;
aDelegate(8); // <- notice the call! No reference to "B" because "B" is already stored in aDelegate
如果您密切關注,當你調用委託(aDelegate(7)
),編譯器在某種程度上需要調用Add
方法上的對象A
會發生什麼樣子,但你看不到,它是隱藏的。代理封裝了對象A
的引用和Add
方法的地址,這就是爲什麼它被稱爲closure
的原因。對比一下當你做aDelegate(8)
時會發生什麼;在對象B
上調用此時間方法Add
,但無法猜測,因爲對象B
的引用再次被隱藏在委託(閉包)中。
我可以兩次投票嗎?快速提問:你說的地方「注意通話!對」A「的引用是隱藏的」......它隱藏了嗎?或者'Delegate''aDelegate'已經有'A'的引用,所以'''A「'不需要傳遞給'aDelegate'的調用?由於''A''已經存儲在'aDelegate'中,所以當在'aDelegate'上調用Invoke並且又調用'Add'時,它只是將'A'的引用作爲第一個參數傳遞給'Add'。 – richard
哎呀,還沒有讀完整個東西......我看到我基本上說過你已經解釋過的同樣的東西。 :-) – richard
那麼你能向我解釋封閉和公開的代表嗎?或者我應該爲此打開一個新的QA? – richard