2012-04-27 6 views
14

मैं निम्नलिखित वर्ग/इंटरफेस:को लागू करने नेस्टेड जेनेरिक इंटरफेस

// Model 
public class A : IA { } 
// ModelLogic 
public class B : IB<A> { } 

// Model Interface 
public interface IA { } 
// ModelLogic Interface 
public interface IB<T> where T : IA { } 

मैं निम्नलिखित कोड का उपयोग कर एक नया उदाहरण बनाने की कोशिश:

IB<IA> foo = new B(); 

मैं निम्न त्रुटि हो रही है:

Cannot implicitly convert type 'B' to 'IB<IA>'. An explicit conversion exists (are you missing a cast?) 

क्या कोई यह बता सकता है कि यह क्यों संभव नहीं है?

+0

सी # का कौन सा संस्करण आप उपयोग कर रहे हैं? – Oded

+3

[कोविरिएंस और कंट्रावायरेंस अकसर किये गए सवाल] (http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx) और [यह ब्लॉग श्रृंखला] (http:/एरिक लिपर्ट – Oded

+1

बी द्वारा /blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/) बीबी एक आईबी है, आईबी नहीं। – Servy

उत्तर

41

ठीक है, के IContainer<T> साथ Aquarium साथ IAnimal साथ Fish साथ A, IA, B, और IB<T> की जगह करते हैं। - foo एक कंटेनर है कि किसी भी जानवर शामिल कर सकते हैं के रूप में लिखा गया

// Model 
public class Fish : IAnimal { } 
public class Tiger : IAnimal { } 
// ModelLogic 
public class Aquarium : IContainer<Fish> 
{ 
    public Fish Contents { get; set; } 
} 

// Model Interface 
public interface IAnimal { } 
// ModelLogic Interface 
public interface IContainer<T> where T : IAnimal 
{ 
    T Contents { get; set; } 
} 

IContainer<IAnimal> foo = new Aquarium(); // Why is this illegal? 
foo.Contents = new Tiger(); // Because this is legal! 

आप foo में एक टाइगर रख सकते हैं: और हम IContainer<T> के एक सदस्य है, और IAnimal की एक दूसरी कार्यान्वयन जोड़ देंगे। लेकिन आप केवल एक मछली को एक्वेरियम में डाल सकते हैं। चूंकि ऑपरेशंस आप Aquarium पर कानूनी रूप से प्रदर्शन कर सकते हैं IContainer<IAnimal> पर किए जा सकने वाले कार्यों की तुलना में अलग-अलग हैं, तो प्रकार संगत नहीं हैं।

सुविधा आप चाहते हैं सामान्य इंटरफ़ेस सहप्रसरण कहा जाता है और यह सी # 4 द्वारा समर्थित है, लेकिन आप संकलक है कि आप अपने मछली टैंक में एक बाघ डाल कभी नहीं होगा करने के लिए साबित करना है। आप क्या करना चाहते हैं: IB पर

// Model 
public class A : IA { } 
// ModelLogic 
public class B : IB<A> { } 

// Model Interface 
public interface IA { } 
// ModelLogic Interface 
public interface IB<out T> where T : IA { } 

सूचना सहप्रसरण एनोटेशन। यह out का अर्थ है कि T केवल आउटपुट के रूप में उपयोग किया जा सकता है, इनपुट के रूप में नहीं। यदि T केवल एक आउटपुट है तो किसी मछली के टैंक में बाघ डालने का कोई तरीका नहीं है क्योंकि वहां "संपत्ति" या विधि संभव नहीं है।

मैंने कई ब्लॉग लेख लिखे थे जबकि हम उस सुविधा को सी # में जोड़ रहे थे; यदि आप डिजाइन संबंधी कि सुविधा में चला गया में रुचि रखते हैं, देखें:

http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/

+0

अमान्य भिन्नता: प्रकार पैरामीटर 'टी' को 'xx.IContainer सामग्री' पर अवास्तविक रूप से मान्य होना चाहिए। 'टी' कॉन्वर्सेंट है। \t मुझे यह त्रुटि मिल रही है। मैं covariant सामान के लिए नया हूँ। त्रुटि का क्या अर्थ है? – Sandeep

+3

@ संदीप: आप किसी भी तरह इनपुट स्थिति में टी का उपयोग कर रहे हैं जब आपने कहा है कि आप इसे केवल आउटपुट स्थिति में उपयोग करने जा रहे हैं। क्या 'सामग्री' एक संपत्ति के साथ एक संपत्ति है? यदि यह स्पष्ट रूप से टी इनपुट इनपुट स्थिति में उपयोग किया जा रहा है, और इसलिए इंटरफ़ेस को टी –

+0

धन्यवाद एरिक में कॉन्वेंट नहीं बनाया जा सकता है। यह हल हो गया। – Sandeep

1

अपने कोड को ठीक करने के लिए, बस बदलने

public interface IB<T> where T : IA { } 

को
public interface IB<out T> where T : IA { } 
+0

एए, एरिक ने मुझे इसे हराया :) – CodingWithSpike

0

यह आसान नहीं है यह देखने के लिए कि आपके पास खाली इंटरफेस कब है।पर विचार करें आप इंटरफ़ेस आईबी में एक विधि एम है: यहाँ

public interface IB<T> where T : IA 
{ 
    void M(T t); 
} 

और बी के कार्यान्वयन है:

public class C : IA { } 

तो:

public class B : IB<A> 
{ 
    public void M(A t) 
    { 
     // only object of type A accepted 
    } 
} 
तो फिर तुम एक वस्तु को C, जो भी आइए लागू करता है

, यदि आपका कोड संभव होगा, तो आप कॉल कर सकते हैं:

IB<IA> foo = new B(); 
foo.M(new C()); 

समस्या यह है कि कक्षा बी केवल ए प्रकार की वस्तुओं को स्वीकार करता है त्रुटि!