2010-01-14 18 views
10

से mscorlib पुस्तकालय (ArgIterator, TypedReference और RuntimeArgumentHandle प्रकार) कुछ विशेष CLI प्रकार सामान्य प्रकार/तरीकों के निर्माण के लिए सामान्य प्रकार पैरामीटर के रूप में इस्तेमाल नहीं किया जा सकता:सी # प्रकार पैरामीटर विनिर्देश

void Foo<T>() { } 
void Bar() { Foo<ArgIterator>(); } 

संकलक त्रुटि प्रदान करता है :

error CS0306: The type 'System.ArgIterator' may not be used as a type argument 

लेकिन यह सी # विनिर्देशन में बिल्कुल दस्तावेज नहीं है।

क्या यह प्रकार सीएलआई विनिर्देश का हिस्सा हैं या सीएलआर कार्यान्वयन द्वारा प्रदान किए गए इस प्रकार और ऊपर वर्णित व्यवहार को सी # spec पर दस्तावेज नहीं किया जाना चाहिए?

+2

और साथ ही साथ आश्चर्य की बात नहीं है। –

उत्तर

10

पहले, जॉन फिर से सही है - इन लोगों बहुत ही खास प्रकार जिनके मान वस्तु के लिए परिवर्तनीय नहीं कर रहे हैं, और इसलिए नहीं किया जा सकता प्रकार तर्क के रूप में प्रयोग किया जाता है। सभी प्रकार के तर्क ऐसे प्रकार होना चाहिए जिनके मूल्य ऑब्जेक्ट में परिवर्तनीय हैं।

प्रलेखन के बारे में आपके प्रश्न का उत्तर करने के लिए:

variadic तरीकों से निपटने के लिए विशेष सुविधाओं में से कोई भी दस्तावेज रहे हैं। वे सी # भाषा का हिस्सा नहीं हैं - भाषा के एक अनुरूप कार्यान्वयन को उन भाषाओं के साथ इंटरऑप करने में सक्षम होने की आवश्यकता नहीं है जो विविध तरीकों का समर्थन करते हैं। कंपाइलर दस्तावेज़ीकरण के हिस्से के रूप में एमएसडीएन में इन सुविधाओं को भी दस्तावेज नहीं किया गया है। ये "आधिकारिक रूप से समर्थित" विशेषताएं नहीं हैं।

यह दुर्भाग्यपूर्ण है, लेकिन केवल इतना बजट उपलब्ध है, और मुझे लगता है कि ज्यादातर लोग इस बात से सहमत होंगे कि हम सुविधाओं को लिखने और पैसे दस्तावेज करने की तुलना में बग ठीक करने के लिए बेहतर करेंगे जो सचमुच 99.99% हमारे उपयोगकर्ता कभी नहीं होंगे , अगर वे समर्थित थे, तब भी कभी भी उपयोग करें, जो वे नहीं हैं।

यदि आप विविधता विधियों के साथ सी # में इंटरऑप करना चाहते हैं, तो आप स्वयं ही हैं। सौभाग्य!

+0

मैं गलत था कि यह विशेषताएं "आधिकारिक" हैं। धन्यवाद, एरिक! :) – ControlFlow

6

मेरा मानना ​​है कि ऐसा इसलिए है क्योंकि इन प्रकारों में "विशेष" है कि उन्हें object में परिवर्तित नहीं किया जा सकता है; केवल प्रकार जिन्हें object में परिवर्तित किया जा सकता है, प्रकार तर्क के रूप में निर्दिष्ट किया जा सकता है। वैसे भी, पॉइंटर्स के लिए भी यही सच है।

मुझे यह नहीं पता कि यह कहां दस्तावेज है (यह 4.4.1 में पॉइंटर्स के लिए प्रलेखित है) लेकिन एरिक लिपर्ट ने दूसरे दिन एक टिप्पणी में इसका उल्लेख किया।

क्या यह सिर्फ रुचि का विषय है, या आप वास्तव में इस तरह की चीज़ों का उपयोग कर कुछ करने की कोशिश कर रहे हैं?

+1

बेशक यह केवल ब्याज और सिंथेटिक उदाहरण है, मैं कुछ सामान्य कोड का परीक्षण mscorlib से सभी क़ीमती प्रकारों के साथ कर रहा था और इस मुद्दे की स्थापना की, लेकिन सी # spec में कोई स्पष्टीकरण नहीं मिला ... मैं समझता हूं कि यह प्रकार बहुत खास हैं, ArgIterator है वास्तव में एक आकार के साथ एक संरचना ... लेकिन कोई स्पष्टीकरण नहीं! :) – ControlFlow

1

आपके द्वारा प्रदान किए गए सभी तीन उदाहरण structs हैं, न कि कक्षाएं, इसलिए मुझे संदेह है कि समस्या की कुंजी है। compiler error message पर प्रलेखन में प्रदान किया गया एक उदाहरण यह भी इंगित करता है कि यदि आप जेनेरिक में किसी प्रकार के पॉइंटर का उपयोग करते हैं तो यह असफल हो जाएगा।

+0

स्ट्रक्चर की अनुमति है और ArgIterator, के लिए, कोई पॉइंटर्स नहीं है। मैंने IntPtr फ़ील्ड युक्त कस्टम स्ट्रक्चर की कोशिश की है और यह ठीक काम करता है। त्रुटि का कारण क्या है यह देखने के लिए संघर्ष। शायद यह बाहरी या असुरक्षित तरीकों से संबंधित है। –

1

धारा 8.2।CLI spec में से 4 मूल्य प्रकारों को कॉल करते हैं जिनमें पॉइंटर्स मूल्यांकन स्टैक "बाईफ-जैसे" प्रकारों में शामिल हो सकते हैं और कहता है कि उन्हें बॉक्स नहीं किया जा सकता है। यह स्पष्ट रूप से System.RuntimeArgumentHandle और System.TypedReference को इस प्रकार के उदाहरणों के रूप में स्पष्ट रूप से कॉल करता है लेकिन एक संपूर्ण सूची प्रदान नहीं करता है। धारा 9.4 यह बताता है कि बायफ प्रकार, बायफ्रू-प्रकार के प्रकार, और System.Void का उपयोग सामान्य प्रकार या विधियों को तुरंत चालू करने के लिए नहीं किया जा सकता है।

1

बस एक टिप्पणी के रूप में, यहां कुछ और मजेदार है जो आप इस प्रकार के कोड को संकलित करने की कोशिश करते समय ऑब्जेक्ट में परिवर्तनीय नहीं हैं। जब आप . (डॉट) टाइप करते हैं तो यहां सभी विधियां विजुअल स्टूडियो द्वारा सुझाव के रूप में आती हैं।

ArgIterator.ReferenceEquals(new object(), new object()); // OK; static method inherited from System.Object 

    var strange = default(ArgIterator); 
    strange.End();   // OK; non-virtual method defined in the struct 
    strange.GetHashCode(); // OK; method overridden in the struct 
    strange.ToString();  // compile-time error; method overriden in System.ValueType, inherited but not overridden in the struct 
    strange.GetType();  // compile-time error; non-virtual method inherited from System.Object