2016-11-08 16 views
5

जब मैं मौजूदा प्रतिनिधि के लिए एक विधि क्या होता है? मेरा मतलब है कि जब मैंने del1 में विधि 1 जोड़ा, तो डेल विधि 1 का पता रखता है। जब मैं Method2 बाद में जोड़ने के लिए, डेल अभी भी Method1 और विधि के लिए अंक 2 का पता यह के तल पर डाला जाता है। क्या इसका मतलब यह नहीं है कि मैंने प्रतिनिधि को बदल दिया? अगर मैं इसे बदल सकता हूं तो किताबों में क्यों कहा जाता है कि "प्रतिनिधि अपरिवर्तनीय हैं"?प्रतिनिधियों अपरिवर्तनीय हैं, लेकिन कैसे?

MyDel del = method1; 
del += method2; 
del += method3; 

उत्तर

5

मुझे एक साधारण सादृश्य का उपयोग करने दें।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; 
+0

मुझे लगता है कि आप समझते हैं कि मैं कहां से संघर्ष कर रहा हूं। धन्यवाद – Lyrk

3
del += method2; 

संकलक की तरह कुछ में इस बदल जाता है:

del = (MyDel)Delegate.Combine(del, method2); 

आप देख सकते हैं, एक नया प्रतिनिधि मूल और अतिरिक्त एक (जो दोनों के रहने से ली गई है अपरिवर्तित), तो परिणाम मूल प्रतिनिधि चर के लिए फिर से सौंपा गया है। (यह केवल प्रतिनिधि वस्तु ही है कि अपरिवर्तनीय है, नहीं चर/क्षेत्र में यह संदर्भित है।)

संबंधित प्रश्न:How does the + operator work for combining delegates?

8

आप नहीं बदल रहे हैं Delegate वस्तु - आप ' किसी भिन्न ऑब्जेक्ट को संदर्भित करने के लिए del को बदलना।

यह तार के साथ के रूप में बिल्कुल वैसा ही है। के एक ही बात में लेकिन तार के साथ अपने कोड में परिवर्तित करते हैं:

string str = "x"; 
str += "y"; 
str += "z"; 

आप str अंत सामग्री "xyz" साथ एक स्ट्रिंग वस्तु का जिक्र है। लेकिन आप सामग्री "x", "y" या "z" के साथ स्ट्रिंग वस्तुओं संशोधित नहीं किया है।

तो यह प्रतिनिधियों के साथ है। जो के बराबर है

del = del + method2; 

:

del = (MyDel) Delegate.Combine(del, method2); 

दूसरे शब्दों में, "एक नया प्रतिनिधि वस्तु जो मंगलाचरण सूचियों मौजूदा दो प्रतिनिधि की चर्चा करते हुए है बनाने

del += method2; 

के बराबर है वस्तुओं "। (यदि del या method2 शून्य है, तो उसे एक नई वस्तु बनाने की आवश्यकता नहीं है।)

अधिक जानकारी के लिए Delegate.Combine देखें।

+0

आपके उदाहरण में, str उस ऑब्जेक्ट का पता धारण कर रहा था जो पहले "x" रखता है। अंत में, str उस ऑब्जेक्ट का पता रख रहा है जिसमें "xyz" है। स्ट्र चर में संग्रहीत पता बदल दिया गया है। क्या इसका मतलब यह नहीं है कि मैंने str बदल दिया? यदि नहीं, तो प्रोग्रामिंग में बदलाव का मतलब अलग-अलग है? – Lyrk

+0

@Lyrk: 'str' परिवर्तनों का मान, ताकि यह एक अलग स्ट्रिंग ऑब्जेक्ट को संदर्भित करता हो। आखिरकार, आप * असाइनमेंट * कर रहे हैं - आप * चर के मान को सेट कर रहे हैं *। क्या यह आपके लिए चीजों को आसान बनाता है यदि आप इसे 'str = str +' y ''के रूप में मानते हैं? आपको क्या लगता है कि 'str + "y' 'अभिव्यक्ति को संदर्भित किया गया है? शायद आपको http://jonskeet.uk/csharp/references.html को पढ़ने की ज़रूरत है। Varlable (जो एक संदर्भ है) और ऑब्जेक्ट के मूल्य के बीच अंतर करना वाकई महत्वपूर्ण है। चर के मान को बदलने से ऑब्जेक्ट को संशोधित नहीं किया जाता है। –

+0

लिंक के लिए धन्यवाद ... – Lyrk

2

और दूसरे शब्दों में एक और संस्करण:

MyDelegate delegateOriginal = Method1; 
MyDelegate copyOfOriginal = delegateOriginal; 


Object.ReferenceEquals(printAllhandler, anotherHandler); // return true 

वापसी ऊपर सच है क्योंकि चर delegateOriginal और एक ही उदाहरण के लिए copyOfOriginal संदर्भ ।

फिर

delegateOriginal += Method2; 

तो delegate परिवर्तनशील अगले अभिव्यक्ति थी तो सच वापस आ जाएगी, क्योंकि चर एक ही वस्तु का संदर्भ लेंगे, लेकिन:

Object.ReferenceEquals(printAllhandler, anotherHandler); // return false 

क्योंकि delegate अपरिवर्तनीय है।
रेखा delegateOriginal += Method2; प्रतिनिधि का नया उदाहरण बनाएगी और इसे मूल चर के संदर्भ में रखेगी।

संबंधित मुद्दे