將方法添加到現有委託會發生什麼?我的意思是當我將方法1添加到del時,del保留了method1的地址。當我添加method2後,del仍然指向Method1,方法2地址插入到它的底部。這不是說我改變了委託嗎?如果我可以改變這個爲什麼在書中被告知「代表是不變的」?代表是不可改變的,但是如何?
MyDel del = method1;
del += method2;
del += method3;
將方法添加到現有委託會發生什麼?我的意思是當我將方法1添加到del時,del保留了method1的地址。當我添加method2後,del仍然指向Method1,方法2地址插入到它的底部。這不是說我改變了委託嗎?如果我可以改變這個爲什麼在書中被告知「代表是不變的」?代表是不可改變的,但是如何?
MyDel del = method1;
del += method2;
del += method3;
讓我用一個簡單的比喻。int
是不變的,所以當你把
int x = 123;
x += 1;
實際上就意味着
int _x = x + 1;
x = _x;
添加一個當
您與代它得到新臨時變量_x
然後下降初始x
_x
;在與會代表的情況下
del += method2;
意味着完全一樣:
delegate _del = delegate.Combine(del, method2);
del = (MyDel) _del;
del += method2;
編譯器變成這樣的事情:
del = (MyDel)Delegate.Combine(del, method2);
正如你可以看到,新的委託從原始和附加一個(兩者仍然得出不變),然後將結果重新分配給原始委託變量。 (這僅是委託對象本身是不可變的,不是變量/字段引用它。)
你不改變Delegate
對象 - 你」重新改變del
以引用不同的對象。
這與字符串完全相同。讓我們轉換代碼爲同樣的事情,但字符串:
string str = "x";
str += "y";
str += "z";
你最終str
提到與內容"xyz"
一個字符串對象。但是您尚未修改內容爲"x"
,"y"
或"z"
的字符串對象。
所以它是與代表。
del += method2;
相當於:
del = del + method2;
這相當於:
del = (MyDel) Delegate.Combine(del, method2);
換言之,「創建具有調用列表指的是現有的兩個代表一個新的委託對象對象」。 (如果del
或method2
爲空,則不需要創建新對象。)
有關更多詳細信息,請參閱Delegate.Combine
。
在你的例子中,str首先持有保存「x」的對象的地址。最後,str保存着包含「xyz」的對象的地址。存儲在str變量中的地址被改變。這不代表我改變了嗎?如果沒有,改變意味着編程中的不同事物? – Lyrk
@Lyrk:'str'的值發生變化,所以它指向一個不同的字符串對象。畢竟,你正在執行*賦值* - 你正在設置變量*的值。如果你認爲它是'str = str +「y」',它會讓事情變得更簡單嗎?你認爲表達式「str +」y「'是指什麼?也許你需要閱讀http://jonskeet.uk/csharp/references.html區分varlable(它是一個引用)的值和對象本身是非常重要的。更改變量的值不會修改對象。 –
謝謝你的鏈接... – Lyrk
而且換言之另一個版本:以上
MyDelegate delegateOriginal = Method1;
MyDelegate copyOfOriginal = delegateOriginal;
Object.ReferenceEquals(printAllhandler, anotherHandler); // return true
,則返回true,因爲變量delegateOriginal
和copyOfOriginal
參照相同的實例。
然後
delegateOriginal += Method2;
如果delegate
是可變的一個表達式,然後將返回true,因爲變量將引用同一個對象,但:
Object.ReferenceEquals(printAllhandler, anotherHandler); // return false
因爲delegate
是不可改變的。
行delegateOriginal += Method2;
將創建委託的新實例並將其引用到原始變量。
我想你明白我在哪裏掙扎。謝謝 – Lyrk