2013-07-23 5 views
5

10.4 Constants में सी # विनिर्देश के अनुसार:जहां टी: वर्ग सामान्य बाधा और स्थिरांक मूल्य घोषणा

प्रकार एक निरंतर घोषणा में निर्दिष्ट, sbyte, बाइट, छोटा है, ushort, पूर्णांक, uint होना चाहिए लंबा, उल, चार, फ्लोट, डबल, दशमलव, बूल, स्ट्रिंग, एनम-टाइप, या संदर्भ-प्रकार। प्रत्येक निरंतर-अभिव्यक्ति को लक्ष्य प्रकार या का मान प्राप्त करना चाहिए जिसे लक्ष्य प्रकार में एक अंतर्निहित रूपांतरण (§6.1) द्वारा परिवर्तित किया जा सकता है।

क्यों तो मैं निम्न कार्य नहीं कर सकते हैं:

public class GenericClass<T> 
    where T : class 
{ 
    public const T val = null; 
} 

कि संभव हो जाना चाहिए, क्योंकि:

  • where T : class का मतलब है कि The type argument must be a reference type; this applies also to any class, interface, delegate, or array type (MSDN से)
  • यह एक और संतुष्ट विनिर्देशों के शब्द: के अलावा संदर्भ-प्रकार के स्थिरांक के लिए एकमात्र संभावित मूल्यnull है।

कोई भी संभावित स्पष्टीकरण?

+0

'टी 'स्वयं ही एक सामान्य प्रकार पैरामीटर कहता है, संदर्भ प्रकार नहीं। – SLaks

+0

जो कोई समझ नहीं आता है। आप 'कॉन्स्ट' को' स्थिर 'में क्यों नहीं बदलते? –

+3

इसके अलावा, आप पृथ्वी पर ऐसा क्यों करना चाहते हैं? – SLaks

उत्तर

0

Eric Lippert स्वीकार किया कि यह एक बग है, और यह अनुमति दी जानी चाहिए:

ऐसा लगता है कि आप एक बग मिला है मुझे करने के लिए लग रहा है; या तो बग विनिर्देशन में है, जिसे स्पष्ट रूप से कॉल करना चाहिए कि टाइप पैरामीटर मान्य प्रकार नहीं हैं, या बग कंपाइलर में है, जो इसे अनुमति देनी चाहिए।

0

संभावित व्याख्या

विचार करें कि CLR सामान्य वर्ग के static सदस्यों initializes या जब यह सामान्य प्रकार पर स्थिर कंस्ट्रक्टर्स invokes। आम तौर पर, जब स्थैतिक प्रारंभ होता है तब स्थिर प्रारंभ होता है; हालांकि, सामान्य वर्ग पहली बार अपने स्थिर सदस्यों को उस वर्ग का एक उदाहरण बनाते हैं।

ध्यान रखें कि एक सामान्य वर्ग एक प्रकार का नहीं है; प्रत्येक एकल T जो कि प्रकार की घोषणा में पारित हो जाता है, एक नया प्रकार बना रहा है।

अब const अभिव्यक्ति पर विचार करें, जिसमें संकलन-समय पर मूल्यांकन की आवश्यकता है। हालांकि टी को कक्षा के रूप में बाध्य किया गया है, और इसलिए यह मान शून्य प्राप्त कर सकता है, परिवर्तनीय val स्मृति में तब तक मौजूद नहीं है जब तक कि कक्षा रनटाइम पर बनाई गई हो।

उदाहरण के लिए, विचार करें कि const T val मान्य थे या नहीं। तब कोड में कहीं हम इस्तेमाल कर सकते हैं:

GenericClass<string>.val 
GenericClass<object>.val 

संपादित

हालांकि दोनों भाव मूल्य null होगा, पूर्व प्रकार string की है और उत्तरार्द्ध प्रकार object की है। संकलक को प्रतिस्थापन करने के लिए, इसे प्रश्न में स्थिरांक की प्रकार परिभाषाओं को जानने की आवश्यकता है।

संकलन समय पर बाधाओं को लागू किया जा सकता है, लेकिन ओपन जेनेरिक रनटाइम तक बंद जेनरिक में परिवर्तित नहीं होते हैं।इसलिए, GenericClass<object>.val प्रतिस्थापन करने के लिए कंपाइलर की स्थानीय मेमोरी में संग्रहीत नहीं किया जा सकता है क्योंकि संकलक जेनेरिक वर्ग के बंद रूप को तुरंत चालू नहीं करता है, और इस प्रकार यह नहीं जानता कि निरंतर अभिव्यक्ति को तुरंत किस प्रकार चालू करना है।

+0

आप स्थिर जेनेरिक और कॉन्स दोनों को गलत समझ रहे हैं। – SLaks

+0

एक सामान्य प्रकार का कन्स्ट्रक्टर (ओपन जेनेरिक क्लास) प्रत्येक पैरामीटर के लिए एक अलग (बंद जेनेरिक) प्रकार बनाता है। इनमें से प्रत्येक प्रकार का एक अलग प्रारंभकर्ता है जो अन्य पैरामीटर के स्वतंत्र रूप से चलता है। यही कारण है कि 'स्थिर रीडोनली टी माईफिल्ड = नया टी() 'लिखना कानूनी है। – SLaks

+0

'const' फ़ील्ड वास्तव में स्मृति में मौजूद नहीं हैं; संकलक संदर्भित करते समय संकलन समय पर उनके मूल्यों को प्रतिस्थापित करता है (यही कारण है कि उन्हें संकलित-प्रकार स्थिरांक होना चाहिए)। कंपाइलर को विभिन्न बंद जेनेरिक प्रकारों के क्षेत्रों के बीच अंतर करने में कोई परेशानी नहीं होगी। संकलन करने के लिए संकलक के लिए – SLaks

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