2011-02-18 25 views
31

इसके साथ क्या गलत है?टी contravariantly मान्य होना चाहिए

interface IRepository<out T> where T : IBusinessEntity 
{ 
    IQueryable<T> GetAll(); 
    void Save(T t); 
    void Delete(T t); 
} 

इसे कहते हैं:

अमान्य विचरण: प्रकार पैरामीटर 'टी' 'MyNamespace.IRepository.Delete (टी)' पर contravariantly मान्य होना चाहिए। 'टी' कॉन्वर्सेंट है।

+1

आपने क्या किया? मुझे एक ही समस्या का सामना करना पड़ रहा है। जवाब वास्तव में इसे हल नहीं करते हैं; मुझे GetAll की आवश्यकता है, उसी श्रेणी में सहेजें और हटाएं – David

+1

क्षमा करें मुझे याद नहीं है। यह 4 साल पहले था। – Eduardo

उत्तर

55

पर विचार करें तो क्या होगा संकलक की अनुमति दी है कि:

interface IR<out T> 
{ 
    void D(T t); 
} 

class C : IR<Mammal> 
{ 
    public void D(Mammal m) 
    { 
     m.GrowHair(); 
    } 
} 
... 
IR<Animal> x = new C(); 
// legal because T is covariant and Mammal is convertible to Animal 
x.D(new Fish()); // legal because IR<Animal>.D takes an Animal 

और तुम सिर्फ एक मछली पर बाल बढ़ने की कोशिश की।

"आउट" का अर्थ है "टी केवल आउटपुट स्थितियों में उपयोग किया जाता है"। आप इसे इनपुट स्थिति में उपयोग कर रहे हैं।

+7

मैं कभी समझ नहीं पाया कि क्यों कुछ समझाते हैं, कैसे 'टी' और' आईआर' और 'सी' और' x' वैध चर नाम हैं। यह विशेष रूप से जेनेरिक के साथ एमएसडीएन दस्तावेज पर भी लागू होता है। "डी" क्या है? – David

+6

@ डेविड: वे मान्य हैं क्योंकि वे सी # विनिर्देश में पहचानकर्ताओं के मानदंडों को पूरा करते हैं, लेकिन मुझे लगता है कि आप का मतलब शैक्षिक रूप से मान्य है। छोटे नामों का उपयोग करने की अध्यापन पाठक को संक्षेप में याद दिलाना है कि यह एक सामान्य, व्यापक रूप से लागू उदाहरण है कि उन्हें सारणी में सोचना चाहिए, न कि विशिष्ट डोमेन में किसी विशिष्ट समस्या का समाधान। –

+0

मैं एक बार मछली पर बाल उग आया। यह मेरे जीवन में एक दिलचस्प समय था। – bubbleking

19

निम्नलिखित दो तरीकों गलत कर रहे हैं:

void Save(T t); 
void Delete(T t); 

आप T विधि तर्क के रूप में नहीं हो सकता। केवल सामान्य प्रकार की वापसी के रूप में यदि आप अपनी सामान्य परिभाषा में इसे covariant (out T) होना चाहते हैं।

या आप contravariance तो आप केवल विधि तर्क के रूप में सामान्य पैरामीटर का उपयोग और नहीं लौट प्रकार सकता है चाहते हैं:

interface IRepository<in T> where T : IBusinessEntity 
{ 
    void Save(T t); 
    void Delete(T t); 
} 
+0

पूर्ण और साफ जवाब। धन्यवाद –

37

आप एक out प्रकार पैरामीटर केवल contravariantly अर्थात वापसी प्रकार में उपयोग कर सकते हैं,। इसलिए, IQueryable<T> GetAll() सही है, लेकिन void Delete(T t) नहीं है।

T के बाद से दोनों सह प्रयोग किया जाता है और contravariantly अपनी कक्षा में, आप out यहाँ (और न ही in) का उपयोग नहीं कर सकते हैं।

यहां कुछ पृष्ठभूमि है: Covariance and Contravariance (Wikipedia)

+10

ध्यान दें कि यह * पैरामीटर में हो सकता है, लेकिन उसके बाद केवल 'एक्शन ' जैसी कुछ चीज़ों के साथ जो दिशा को फिर से उलट देता है। –

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