2016-03-08 5 views
6

संकलक इस कोड का अनुवाद करना चाहिएसी # कंपाइलर संभाल स्पष्ट कास्ट ऑपरेटरों को ओवरलोडिंग कैसे करता है?</p> <p>दो तरीके में एक ही नाम और हस्ताक्षर है, लेकिन उनकी वापसी प्रकार है, उदा केवल अलग है कि:

public static Int64 ExplicitCast(MyNumber n) 
... 

public static Double ExplicitCast(MyNumber n) 
... 

हालांकि, हमें उन तरीकों की अनुमति नहीं है जो केवल उनके रिटर्न प्रकार से भिन्न हों। पर्दे के पीछे क्या होता है?

+1

_ "संकलक का अनुवाद होना चाहिए" _ - कौन कहता है? – CodeCaster

+3

सीमा सी # कंपाइलर में है, आईएल असेंबली कोड में नहीं। तो सी # कंपाइलर आईएल कोड उत्पन्न कर सकता है जो सी # में लिखना अवैध होगा। – xanatos

उत्तर

7

तकनीकी तौर पर सीएलएस (आम भाषा विशिष्टता, एक विनिर्देश जो .NET आभासी मशीन है कि सभी नेट भाषाओं का समर्थन करना चाहिए की एक subsect उल्लेख करें) का कहना है कि स्पष्ट डाली विधि का नाम होना चाहिए op_Explicit (देखें उदाहरण के लिए http://goo.gl/wn8dHq)।

सीमा है कि आपके पास एक ही नाम के साथ कई विधियां नहीं हो सकती हैं और केवल अलग-अलग रिटर्न प्रकार सी # की सीमा है। आईएल भाषा (वह .NET वर्चुअल मशीन की भाषा है) में यह सीमा नहीं है।

उदाहरण के लिए देखें: https://stackoverflow.com/a/442100/613130

कुछ भाषाओं (जैसे MSIL के रूप में), तथापि, वापसी प्रकार से अधिक भार के लिए अनुमति देते हैं। वे भी पाठ्यक्रम की उपरोक्त कठिनाई का सामना करते हैं, लेकिन उनके पास कामकाज है, जिसके लिए आपको उनके दस्तावेज़ीकरण से परामर्श करना होगा।

और https://blogs.msdn.microsoft.com/abhinaba/2005/10/07/c-cil-supports-overloading-by-return-type/

हालांकि, सीआईएल वापसी प्रकार से समर्थन ओवरलोडिंग तरीकों करता है, भले ही सी #, वीबी नहीं करता है। रूपांतरण ऑपरेटर ओवरलोडिंग सी # संकलक इस सुविधा (मैं एक प्रयोग के बारे में पता है और मुझे यकीन है कि वहाँ अधिक हैं कि :) हूँ)

अगर आप चाहते हैं (है कि वास्तव में मामला यहाँ से पूछा है) का उपयोग करता है लागू करने के लिए ECMA-335 मानक को देखने के लिए:

I.8.11.1 विधि परिभाषाओं

विधि हस्ताक्षर बुला सम्मेलन, विधि के लिए मापदंडों के प्रकार को परिभाषित करता है, और विधि की वापसी प्रकार

आप को पता है कि कैसे विधि कहा जा सकता है रुचि रखते हैं ... खैर ... आईएल भाषा वापसी प्रकार से अधिभार का समर्थन करता है जाहिर है, तो इसकी call अनुदेश का समर्थन करना चाहिए यह

उदाहरण http://goo.gl/CS4FPb के लिए :-):

call int64 MyNumber::op_Explicit(class MyNumber) 

बनाम

call float64 MyNumber::op_Explicit(class MyNumber) 

ध्यान दें कि सीएलएस सामान्य रूप से रिटर्न प्रकार के आधार पर ओवरलोडिंग को रोकता है ...

सीएलएस नियम 38:: गुण और विधियों के आधार अतिभारित किया जा सकता लेकिन यह op_Implicit (अंतर्निहित डाली ऑपरेटर) और op_Explicit के लिए एक अपवाद (स्पष्ट डाली ऑपरेटर) (समान ECMA-335 फ़ाइल से) है केवल की संख्या और प्रकारों पर, उनके पैरामीटर, op_Implicit और op_Explicit नामक रूपांतरण ऑपरेटरों को छोड़कर, को उनके रिटर्न प्रकार के आधार पर ओवरलोड किया जा सकता है।

+0

शायद यह जोड़ना चाहें कि सीएलआर कोई 'असली' ओवरलोड रिज़ॉल्यूशन नहीं करता है। यह सदस्य को देखने के लिए बस सटीक हस्ताक्षर का उपयोग करता है - और फिर सदस्य को कॉल करता है (यदि आवश्यक हो तो आभासी)। वास्तविक _overload resolution_ संकलक में होता है (या यदि आपको पसंद है तो 'गतिशील' में); अधिभारित सदस्य सीआईएल में (निर्दिष्ट नियमों के साथ) _defined_ हैं और केवल मान्य हैं। – atlaste

+0

:-) यह वही है जो एटलास्ट ने कहा :-) – xanatos

1

मुझे यकीन नहीं है कि आपके प्रश्न का उद्देश्य है, इसलिए यह सबसे अच्छा जवाब है जो मैं आपको दे सकता हूं। ऊपर दिए गए कोड इस

MyNumber.op_Explicit: 
IL_0000: nop   
IL_0001: ldarg.0  
IL_0002: callvirt UserQuery+MyNumber.ToInteger 
IL_0007: stloc.0  
IL_0008: br.s  IL_000A 
IL_000A: ldloc.0  
IL_000B: ret   

MyNumber.op_Explicit: 
IL_0000: nop   
IL_0001: ldarg.0  
IL_0002: callvirt UserQuery+MyNumber.ToDouble 
IL_0007: stloc.0  
IL_0008: br.s  IL_000A 
IL_000A: ldloc.0  
IL_000B: ret  

कारण ऐसा लगता है जैसे कुछ करने के लिए संकलित "असंगत" क्योंकि कीवर्ड explicit operator की है। यह संकलक को एक स्पष्ट कलाकार में जिस तरीके से करता है उससे अलग कोड उत्पन्न करने के लिए कहता है।

आप इसे बिना कुछ इस तरह मिल चाहते हैं:

MyNumber.Double2: 
IL_0000: nop   
IL_0001: ldarg.0  
IL_0002: callvirt UserQuery+MyNumber.ToDouble 
IL_0007: stloc.0  
IL_0008: br.s  IL_000A 
IL_000A: ldloc.0  
IL_000B: ret  
संबंधित मुद्दे