मैं एक Microsoft कनेक्ट आलेख का पता लगाने में सक्षम था जो इस मुद्दे पर कुछ विस्तार से चर्चा करता है:
दुर्भाग्यवश, यह व्यवहार डिजाइन द्वारा है और प्रकार के मापदंडों के उपयोग को सक्षम करने के लिए एक आसान समाधान नहीं है जिसमें मूल्य प्रकार शामिल हो सकते हैं।
यदि प्रकार को संदर्भ प्रकार के रूप में जाना जाता है, तो संदर्भ समानता के लिए ऑब्जेक्ट परीक्षण चर पर परिभाषित डिफ़ॉल्ट अधिभार, हालांकि एक प्रकार अपने स्वयं के कस्टम अधिभार को निर्दिष्ट कर सकता है। संकलक यह निर्धारित करता है कि चर के स्थिर प्रकार के आधार पर किस अधिभार का उपयोग किया जाए (निर्धारण बहुरूपी नहीं है)। इसलिए, यदि आप जेनेरिक प्रकार के पैरामीटर T को एक गैर-सील संदर्भ प्रकार (जैसे अपवाद) के लिए विवश करने के लिए अपना उदाहरण बदलते हैं, तो संकलक विशिष्ट अधिभार का उपयोग करने के लिए निर्धारित कर सकता है और निम्नलिखित कोड संकलित करेगा:
public class Test<T> where T : Exception
यदि प्रकारों को मूल्य प्रकारों के लिए जाना जाता है, तो उपयोग किए गए सटीक प्रकारों के आधार पर विशिष्ट मूल्य समानता परीक्षण करता है। यहां कोई भी "डिफ़ॉल्ट" तुलना नहीं है क्योंकि संदर्भ तुलना मूल्य प्रकारों पर सार्थक नहीं है और संकलक यह नहीं जान सकता कि उत्सर्जन की तुलना में कौन सा विशिष्ट मूल्य है। कंपाइलर ValueType.Equals (ऑब्जेक्ट) पर कॉल का उत्सर्जन कर सकता है, लेकिन यह विधि प्रतिबिंब का उपयोग करती है और विशिष्ट मूल्य तुलना की तुलना में काफी अक्षम है। इसलिए, भले ही आप टी पर एक मूल्य-प्रकार की बाधा निर्दिष्ट करने के लिए थे, यहां संकलक के लिए कुछ भी उचित नहीं है:
public class Test<T> where T : struct
आपके द्वारा प्रस्तुत किए गए मामले में, जहां कंपाइलर को यह भी पता नहीं है कि टी एक मूल्य या संदर्भ प्रकार है, तो समान रूप से उत्पन्न करने के लिए कुछ भी नहीं है जो सभी संभव प्रकारों के लिए मान्य होगा। एक संदर्भ तुलना मूल्य प्रकारों के लिए मान्य नहीं होगी और कुछ प्रकार के मूल्य तुलना संदर्भ प्रकारों के लिए अप्रत्याशित होगी जो ओवरलोड नहीं करते हैं।
यहाँ आप क्या कर सकते हैं ...
मैंने पुष्टि की है कि ये दोनों विधियाँ संदर्भ और मूल्य प्रकारों की एक सामान्य तुलना के लिए काम करती हैं:
object.Equals(param, default(T))
या
EqualityComparer<T>.Default.Equals(param, default(T))
"==" ऑपरेटर के साथ तुलना करने के लिए आपको इनमें से किसी एक विधि का उपयोग करना होगा:
यदि किसी ज्ञात आधार वर्ग से टी के सभी मामले आप संकलक को सामान्य प्रकार के प्रतिबंधों का उपयोग करने दे सकते हैं।
public void MyMethod<T>(T myArgument) where T : MyBase
कंपाइलर तब पहचानता है कि ऑपरेशन कैसे करना है MyBase
और "ऑपरेटर" को नहीं फेंकेंगे == '' टी 'और' टी 'की त्रुटि वाले ऑपरेंड पर लागू नहीं किया जा सकता है जो अब आप देख रहे हैं।
एक अन्य विकल्प टी को किसी भी प्रकार से लागू करने के लिए प्रतिबंधित करना होगा IComparable
।
public void MyMethod<T>(T myArgument) where T : IComparable
और फिर IComparable इंटरफ़ेसCompareTo
द्वारा परिभाषित विधि का उपयोग करें ।
if (myArgument?.Equals( default(T) ) != null )
।