2009-03-17 11 views
78

ildasm और सी # प्रोग्राम का उपयोग करना उदा।एमएसआईएल विधि में hidebysig का उद्देश्य क्या है?

static void Main(string[] args) 
{ 

} 

देता है:

.method private hidebysig static void Main(string[] args) cil managed 
{ 
    .entrypoint 
    // Code size  2 (0x2) 
    .maxstack 8 
    IL_0000: nop 
    IL_0001: ret 
} // end of method Program::Main 

hidebysig निर्माण क्या करता है?

उत्तर

145
ECMA 335 से

, विभाजन 1 की धारा 8.10.4:

सीटीएस दोनों के नाम (छुपा) और में लेआउट स्लॉट की बंटवारे कि एक आधार प्रकार से दिखाई हैं पर स्वतंत्र नियंत्रण प्रदान करता है व्युत्पन्न कक्षा (ओवरराइडिंग)। छिपाने व्युत्पन्न कक्षा में किसी सदस्य को चिह्नित करके नियंत्रित किया गया है या तो नाम से छुपाएं या नाम-और-हस्ताक्षर से छिपाएं। छिपाने हमेशा सदस्य के के आधार पर किया जाता है, यानी फ़ील्ड नाम बेस फ़ील्ड नाम छुपा सकते हैं, लेकिन विधि नाम, संपत्ति नाम या ईवेंट नाम नहीं हैं। यदि व्युत्पन्न सदस्य नाम से छिपी हुई चिह्नित है, तो के सदस्य के साथ बेस क्लास में समान प्रकार के समान नाम व्युत्पन्न कक्षा में दिखाई नहीं दे रहे हैं; यदि सदस्य नाम-और-हस्ताक्षर से छिपा हुआ है तो केवल उसी प्रकार के सदस्य के साथ समान नाम और प्रकार (फ़ील्ड के लिए) या विधि हस्ताक्षर (विधियों के लिए) व्युत्पन्न कक्षा से छिपा हुआ है। छिपाने के इन दो रूपों के बीच भेद का कार्यान्वयन पूरी तरह से स्रोत भाषा संकलक और प्रतिबिंब पुस्तकालय द्वारा प्रदान किया गया है; इसका वीईएस पर कोई प्रत्यक्ष प्रभाव नहीं पड़ता है।

(ऐसा नहीं है कि से तुरंत स्पष्ट नहीं है, लेकिन hidebysig का अर्थ है "नाम व हस्ताक्षर से छिपाने"।)

इसके अलावा विभाजन 2 की धारा 15.4.2.2 में

:

hidebysig है उपकरण के उपयोग के लिए आपूर्ति की गई और वीईएस द्वारा अनदेखा किया गया है। यह निर्दिष्ट करता है कि घोषित विधि बेस क्लास प्रकारों के सभी विधियों को छुपाती है जिनके मिलान विधि हस्ताक्षर हैं; जब छोड़ा जाता है, तो हस्ताक्षर के बावजूद विधि को उसी नाम के सभी विधियों को छिपाना चाहिए। ,

public class Base 
{ 
    public void Bar() 
    { 
    } 
} 

public class Derived : Base 
{ 
    public void Bar(string x) 
    { 
    } 
} 

... 

Derived d = new Derived(); 
d.Bar(); 

कि वैध है, क्योंकि Bar(string)नहीं छिपाने Bar() है, क्योंकि सी # संकलक hidebysig उपयोग करता है:

उदाहरण के लिए, मान लीजिए आप कर सकते है। यदि यह "नाम से छिपाने" अर्थशास्त्र का उपयोग करता है, तो आप Bar() को Derived के संदर्भ पर बिल्कुल कॉल नहीं कर पाएंगे, हालांकि आप इसे अभी भी आधार पर डाल सकते हैं और इसे इस तरह कॉल कर सकते हैं।

संपादित करें:

Derived d = new Derived(); 
d.Bar(); 

Test.cs(6,9): error CS1501: No overload for method 'Bar' takes '0' arguments 
: मैं सिर्फ एक DLL करने के लिए उपरोक्त कोड संकलन है, यह ildasming, Bar() और Bar(string) के लिए hidebysig को दूर करने, इसे फिर से ilasming, तो अन्य कोड से Bar() कॉल करने के लिए कोशिश कर रहा द्वारा इस की कोशिश की है

हालांकि:

Base d = new Derived(); 
d.Bar(); 

(कोई संकलन समस्याओं।)

+2

में [सारांश] (http://stackoverflow.com/a/4760614/256431 "छाया बनाम VB.NET में Overloads"), यह 'Shadows' और VB.NET में' Overloads' के बीच का अंतर है। –

14

स्कीट के जवाब के अनुसार, इसके अलावा इसका कारण यह है कि जावा और सी # कक्षा के क्लाइंट को उसी वर्ग के साथ किसी भी तरीके से कॉल करने की अनुमति देता है, जिसमें बेस क्लास शामिल हैं। जबकि सी ++ नहीं करता है: यदि व्युत्पन्न वर्ग बेस क्लास में एक विधि के समान नाम के साथ एक भी विधि को परिभाषित करता है, तो क्लाइंट बेस क्लास विधि को सीधे कॉल नहीं कर सकता है, भले ही यह वही तर्क न ले। इसलिए सुविधा को अधिभारित करने के दोनों दृष्टिकोणों का समर्थन करने के लिए सीआईएल में शामिल किया गया था।

सी ++ में आप बेस क्लास से using निर्देश के साथ ओवरलोड के नामित सेट को प्रभावी रूप से आयात कर सकते हैं, ताकि वे उस विधि नाम के लिए "ओवरलोड सेट" का हिस्सा बन सकें।

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