2012-02-20 13 views
13

अद्यतन: निम्न कोड केवल सी # 4.0 (दृश्य स्टूडियो 2010)सहप्रसरण/contravariance: कैसे निम्नलिखित कोड बनाने के लिए संकलन

में समझ ऐसा लगता है जैसे मैं सहप्रसरण से कुछ गलतफहमी हो रहा है बनाता है/contravariance बात । क्या कोई मुझे बता सकता है कि निम्न कोड संकलित क्यों नहीं करता है?

public class TestOne<TBase> 
{ 
    public IEnumerable<TBase> Method<TDerived>(IEnumerable<TDerived> values) 
     where TDerived: TBase 
    { 
     return values; 
    } 
} 

यह एक संकलित करते हुए: (!!!)

public interface IBase 
{ 
} 
public interface IDerived: IBase 
{ 
} 
public class TestTwo 
{ 
    public IEnumerable<IBase> Method(IEnumerable<IDerived> values) 
    { 
     return values; 
    } 
} 

उत्तर

13

सहप्रसरण केवल, प्रकार संदर्भ के लिए (प्रकार तर्क के लिए) लागू होता है तो आप एक वर्ग बाधा जोड़ने के लिए:

public IEnumerable<TBase> Method<TDerived>(IEnumerable<TDerived> values) 
    where TDerived : class, TBase 
{ 
    return values; 
} 

यह आपको IEnumerable<int> को IEnumerable<object> में परिवर्तित करने की कोशिश करने से रोक देगा, जो अमान्य है।

+0

@Adam: मेरा मानना ​​है कि आप गलत हैं, 'IEnumerable ' 'नहीं IEnumerable ' डिफ़ॉल्ट तो यह '3.5' – sll

+1

में भी @AdamMihalcin संकलन नहीं होता कर रहा है: नहीं, यह कोड * नहीं होता * .NET 4 से पहले संकलित किया है। मैंने इसे सत्यापित करने के लिए अभी कोशिश की है। सामान्य आविष्कार के बिना, 'IENumerable ' से 'IENumerable 'का रूपांतरण केवल अमान्य है। –

+0

टीएसपर पर अच्छी कॉल, बस तय किया गया है कि –

1

मैं किसी भी परिस्थिति के बारे में सोच नहीं सकता जहां आपको वास्तव में TDerived की आवश्यकता है। TBase का उपयोग करना पर्याप्त है:

public class TestOne<TBase> 
{ 
    public IEnumerable<TBase> Method(IEnumerable<TBase> values) 
    { 
     return values; 
    } 
} 

सब के बाद, आप के बारे में TDerived तथ्य से अलग है कि यह एक TBase है कोई जानकारी नहीं है ...

+2

दुर्भाग्यवश यह जटिलता के लिए मैंने कुछ नहीं बनाया है, यह एक वास्तविक स्थिति है जिसे मैं समाप्त कर रहा हूं मेरे कोड में –

+1

@bonomo: यह दिलचस्प है, मुझे भविष्य के संदर्भ के लिए एक और विस्तृत उदाहरण देखना अच्छा लगेगा। :-) – linepogl

0

न तो शुरू में मेरे लिए संकलित। दोनों सुपर (टी/आई) से आधार (टी/आई) के निहित कलाकारों पर असफल रहे। जब मैंने एक स्पष्ट मामला जोड़ा, हालांकि, दोनों संकलित।

public IEnumerable<TBase> Method<TSuper>(IEnumerable<TSuper> values) 
    where TSuper: TBase 
    { 
     return (IEnumerable<TBase>) values; 
    } 
संबंधित मुद्दे