2012-09-18 28 views
22

विधि को संकलित किए जाने पर संपत्ति को त्रुटि क्यों मिलती है?अमान्य भिन्नता: प्रकार पैरामीटर 'टी' को 'UserQuery.IItem <T> .ememist' पर contravariantly मान्य होना चाहिए। 'टी' covariant

public interface IFoo {} 
public interface IBar<out T> where T : IFoo {} 

public interface IItem<out T> where T: IFoo 
{ 
    // IEnumerable<IBar<T>> GetList(); // works 
    IEnumerable<IBar<T>> ItemList { get; set; } // Error! 
} 

त्रुटि:

Invalid variance: The type parameter 'T' must be contravariantly valid on 'UserQuery.IItem<T>.ItemList'. 'T' is covariant.

+0

की संभावित डुप्लिकेट [टी contravariantly मान्य होना चाहिए] (https://stackoverflow.com/questions/5041664/t-must-be-contravariantly-valid) –

उत्तर

27

आप संकलक त्रुटि मिलती है, क्योंकि आप एक संपत्ति गेटर (get) और एक सेटर (set) है। प्रॉपर्टी गेटटर के पास T है, इसलिए out काम करता है, लेकिन प्रॉपर्टी सेटर में T होगा, इसलिए इसे in संशोधक की आवश्यकता होगी।

क्योंकि आप T आप सेटर हटाने की जरूरत पर out है और यह संकलन होगा:

public interface IItem<out T> where T : IFoo 
{ 
    // IEnumerable<IBar<T>> GetList(); // works 
    IEnumerable<IBar<T>> ItemList { get; } // also works 
} 

यदि आपका T एक in सामान्य तर्क उसके बाद निम्न काम करेगा है:

public interface IItem<in T> where T : IFoo 
{ 
    IEnumerable<IBar<T>> ItemList { set; } 
} 

लेकिन आपके पास एक ही समय में दोनों (out,in) नहीं हो सकते हैं, इसलिए आपके पास गेटटर और एक सेटर के साथ सह/contravariant संपत्ति नहीं हो सकती है।

public interface ISubFoo : IFoo { } 

IItem<ISubFoo> item = //whatever 
item.ItemList = new List<IBar<IFoo>>>(); 

जो टाइप सुरक्षित नहीं है:

+2

मुझे यह समझ में नहीं आता। आप प्राप्त करने के लिए, सेट में, संबंधित है। मैं इसका उपयोग क्यों नहीं कर सकता, क्योंकि इसका मतलब है "इस प्रकार या किसी व्युत्पन्न प्रकार"। यदि बी ए से निकला है, तो मैं इंटरफ़ेस पर किसी भी संपत्ति को बी पास क्यों नहीं कर सकता जिसके लिए ए को ए की आवश्यकता होती है, क्योंकि बी को केवल वैसे ही कहा जाएगा जैसे यह ए भी था। समस्या क्या है और इसमें से किसी के साथ क्या करना है? कहता है "इस प्रकार या किसी भी आधार प्रकार"। मैं नहीं चाहता कि जैसा कि मैं कम से कम ए के व्यवहार सेट का उपयोग करने की उम्मीद कर रहा हूं, एक "ए" पास करने से इसे काट नहीं दिया जाएगा। तो मैं "अंदर" नहीं चाहता ... लेकिन मैं बी को आउट ए में सेट करने में सक्षम होना चाहता हूं। – rism

2

सेटर, क्योंकि अगर यह थे आप ऐसा करने में सक्षम हो जाएगा अनुमति नहीं है।