2012-12-05 12 views
6

अनुमति नहीं मैं हाल ही में यह लिखा और आश्चर्य हुआ कि यह संकलित:जेनेरिक्स अनुमति की ओर जाता है और अस्पष्टता

public class MyGeneric<U, V> { 
    MyGeneric(U u) { ... } 
    MyGeneric(V v) { ... } 
    public void Add(U u, V v) { ... } 
    public void Add(V v, U u) { ... } 
} 

इस प्रकार अगर मैं इस वर्ग का उपयोग करें, मैं एक "अस्पष्ट निर्माता संदर्भ" मिल और यदि मैं जोड़ता हूं तो एक "संदिग्ध आमंत्रण"।

var myVar = new MyGeneric<int, int>(new MyIntComparer()); 

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

var myVar = new MyGeneric<int, double>(new MyIntComparer()); 
myVar.Add(3, 5); 

तो मैंने सोचा कि निम्नलिखित की अनुमति भी थी, लेकिन आश्चर्य की बात है कि मुझे एक त्रुटि मिली। निम्नलिखित संकलन करने की अनुमति क्यों नहीं है?

public interface IMyInterface<T, S> { 
    void Add(T t, S s); 
} 

public class MyGeneric<U, V> : IMyInterface<U, V>, IMyInterface<V, U> { 
    public MyGeneric(U u) { } 
    public MyGeneric(V v) { } 
    void IMyInterface<U, V>.Add(U u, V v) { ... } 
    void IMyInterface<V, U>.Add(V v, U u) { ... } 
} 

बावजूद अगर मैं अस्पष्ट या स्पष्ट इंटरफेस कार्यान्वयन का उपयोग, संकलक कहा गया है कि

'MyGeneric < यू, वी >' दोनों 'IMyInterface < यू, वी >' और 'IMyInterface लागू नहीं कर सकते < वी, यू > 'क्योंकि वे कुछ प्रकार पैरामीटर प्रतिस्थापन

और पहले एलो क्यों हैं लिखने के लिए wed?

+2

हालांकि [इन] (http://blogs.msdn.com/b/ericlippert/archive/2006/04/05/odious-ambiguous-overloads-part-one.aspx) [दो] (http: // blogs.msdn.com/b/ericlippert/archive/2006/04/06/odious-ambiguous-overloads-part-two.aspx) ब्लॉग पोस्ट उस मामले के बारे में बात कर रहे हैं जहां एक सामान्य विधि और एक गैर-सामान्य विधि समाप्त हो सकती है कुछ प्रकार के तर्कों के लिए एक ही हस्ताक्षर के साथ, वे आपके दो-प्रकार-तर्क मामले पर भी लागू हो सकते हैं। (इसका उत्तर दिया गया है कि यह क्यों अनुमति है, अनिवार्य रूप से "हमने इसे सी # 2.0 में अनुमति दी है और अब इसे बदलने में बहुत देर हो चुकी है"। – Rawling

+0

इन लिंक के लिए धन्यवाद, यह संकलक का कार्यान्वयन स्पष्टीकरण है जिसे मैं – AlexH

+0

@ राउलिंग, दिलचस्प लिंक के लिए धन्यवाद। – Andreas

उत्तर

4

1- निम्नलिखित को संकलित करने की अनुमति क्यों नहीं है? प्रतिक्रिया की

भाग उस पोस्ट में है: Why does the C# compiler complain that "types may unify" when they derive from different base classes?

सी # 4 विनिर्देश राज्यों की धारा 13.4.2:

इंटरफेस एक सामान्य प्रकार घोषणा द्वारा कार्यान्वित सभी के लिए अद्वितीय रहना चाहिए संभव निर्मित प्रकार। इस नियम के बिना, कुछ निर्मित प्रकारों के लिए कॉल करने के लिए सही विधि निर्धारित करना असंभव होगा।

2- और पहली बार लिखने की अनुमति क्यों है?

संकलक संकलन समय पर सामान्य प्रकार की जांच, सी # 4 विनिर्देश राज्यों की धारा 7.4.3.5 करते हैं:

जबकि हस्ताक्षर के रूप में घोषित अद्वितीय होना चाहिए, यह संभव है कि प्रकार तर्कों की प्रतिस्थापन समान हस्ताक्षर में परिणाम। ऐसे मामलों में, ऊपर अधिभार रिज़ॉल्यूशन के टाई-ब्रेकिंग नियम सबसे विशिष्ट सदस्य चुनते हैं।निम्न उदाहरण भार के कि वैध और अवैध इस नियम के अनुसार कर रहे हैं दिखाने:

interface I1<T> {...} 
interface I2<T> {...} 
class G1<U> 
{ 
    int F1(U u);     // Overload resulotion for G<int>.F1 
    int F1(int i);     // will pick non-generic 
    void F2(I1<U> a);    // Valid overload 
    void F2(I2<U> a); 
} 
class G2<U,V> 
{ 
    void F3(U u, V v);   // Valid, but overload resolution for 
    void F3(V v, U u);   // G2<int,int>.F3 will fail 
    void F4(U u, I1<V> v);  // Valid, but overload resolution for 
    void F4(I1<V> v, U u);  // G2<I1<int>,int>.F4 will fail 
    void F5(U u1, I1<V> v2); // Valid overload 
    void F5(V v1, U u2); 
    void F6(ref U u);    // valid overload 
    void F6(out V v); 
} 
+0

विस्तृत स्पष्टीकरण के लिए धन्यवाद। यह सच है कि MyGeneric मूल रूप से एक ही इंटरफ़ेस को दो बार लागू करेगा और यही कारण है कि यह पैरामीटर प्रतिस्थापन के बारे में शिकायत करता है। – Andreas

1

के रूप में स्वीकार जवाब यहाँ में विस्तार से बताया यह भाषा विनिर्देश का हिस्सा है:

Why does the C# compiler complain that "types may unify" when they derive from different base classes?

धारा सी # 4 विनिर्देशन के 13.4.2 में कहा गया है:

यदि कोई संभव बनाया गया है सी से बनाए गए प्रकार, प्रकार के तर्क एल में प्रतिस्थापित किए जाने के बाद, एल में दो इंटरफेस समान होने के कारण होते हैं, फिर सी की घोषणा अमान्य है। सभी संभव निर्मित प्रकारों का निर्धारण करते समय सीमित घोषणाओं पर विचार नहीं किया जाता है।

मैं अपने दो उदाहरण के बीच अंतर लगता है कि दूसरी इंटरफेस का उपयोग करता है (डुप्लिकेट के लिए जाँच की, भाषा कल्पना के अनुसार) लेकिन पहले प्रकार का उपयोग करता है (डुप्लिकेट के लिए जाँच नहीं की, संभवतः के कारण अस्पष्टता के रूप में आप को देखा है के बावजूद) है ।

+0

धन्यवाद, हाँ यह सच है, यह मूल रूप से एक ही इंटरफ़ेस से दो बार प्राप्त होगा। – Andreas

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