2017-09-28 7 views
8

के साथ जेनेरिक contravariant का उपयोग कर मैं सी # जेनेरिक सीख रहा हूँ और परीक्षण उद्देश्यों के लिए कुछ डमी कोड बना रहा हूँ। तो, मैं in Generic Modifier का परीक्षण कर रहा हूं, जो निर्दिष्ट करता है कि प्रकार पैरामीटर contravariant है।IList और IENumerable

नीचे इंटरफेस को देखते हुए:

[CS1961] अमान्य विचरण: प्रकार पैरामीटर 'टी' invariantly होना चाहिए वैध

public interface IInterfaceTest<in T> 
{ 
    void Method(T value); 
    void Method(IList<T> values); 
    void Method(IEnumerable<T> values); 
} 

जब संकलन, मैं त्रुटि संदेश मिल रहा 'IInterfaceTest.Method (IList)' पर। 'टी' contravariant है।

त्रुटि केवल void Method(IEnumerable<T> values) लाइन से संबंधित है। यदि यह लाइन हटा दी गई है, तो सभी ठीक काम करते हैं।

तो मेरे सवाल है: मैं IEnumerable साथ सामान्य contravariant का उपयोग क्यों कर सकते हैं लेकिन IList साथ नहीं करता है? क्या मैं कुछ भूल गया हूँ?

धन्यवाद।

+5

'IList ' नहीं है, और नहीं हो सकता है, covariant। – SLaks

+2

@ स्लक्स: मुझे लगता है कि ओपी इसे प्राप्त करता है, लेकिन क्यों? (जो मुझे भी मदद करेगा) – Stefan

+6

क्योंकि यह उत्परिवर्तनीय है। https://stackoverflow.com/a/2033921/34397 – SLaks

उत्तर

4

सवाल क्यों यह IList<T> के लिए अनुमति नहीं है टिप्पणी में जवाब दिया गया है और पहले से ही लिंक सवाल: IList<T>T में अपरिवर्तनीय और इसलिए एक विपरीत संस्करण Tनहीं यहाँ जो भी इस्तेमाल किया जा सकता है।

मुझे पहले क्या परेशान किया गया यह तथ्य है कि Method(IEnumerable<T>) यहां अनुमति है। अजीब चीज यह है कि भिन्नता है जब आप का उपयोग के लिए एक अन्य तर्क प्रकार के लिए करते हैं।

कल्पना कीजिए।

public interface ITestInterface<in T> 
{ 
    void Method(IEnumerable<T> e); 
    IEnumerable<T> GetMethod(); // illegal 
} 
public class Animal {} 
public class Lion : Animal [} 
public class Gnu : Animal {} 

ITestInterface<Animal> animals; 
ITestInterface<Lion> lions; 
ITestInterface<Gnu> gnus; 

अब T में ITestInterface<in T> के विपरीत विचरण हमें बताता है कि आप

lions = animals; 

कर सकते हैं और जब आप lions.Method(e) कहते हैं, आप केवल एक IEnumerable<Lion> प्रदान कर सकते हैं। तो Method का कोड केवल Lion s का अनुमान लगा सकता है, जो सभी Animalsanimals.Method() अपेक्षाओं के साथ हैं। सब कुछ ठीक है।

दूसरी ओर, IEnumerable<T> GetMethod(), गैर कानूनी है क्योंकि:

gnus = animals; 

कानूनी है, और अब gnu.GetMethod() एक IEnumerable<Animal> लौट जहां एक IEnumerable<Gnu> उम्मीद थी होगा। और जब आप पुनरावृत्त होते हैं, तो जानवरों का आश्चर्य उठाने से उस अनुक्रम में इंतजार हो सकता है।

+2

'टी' के संबंध में भिन्नता _inputs_ के लिए" चारों ओर बदल दी गई है "जिसका संबंध' टी' है। 'टी' के संबंध में आउटपुट में समान भिन्नता होनी चाहिए। उदाहरण के लिए, 'एक्शन GetMethod() 'मान्य होगा क्योंकि' एक्शन <-T> '' टीटी' के साथ बदलता है जैसे 'ITestInterface <-T>'। इसके अलावा, अच्छा जवाब। –

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