2010-10-31 7 views
6

इंटरफेस/जेनेरिक के बारे में कुछ मौलिक होना चाहिए जो मैंने अभी तक नहीं सीखा है। मुझे अब यह सीखने की उम्मीद है।इंटरफेस की सूची एक कार्यान्वयन प्रकार का उपयोग क्यों नहीं कर सकती?

मैं इस इंटरफेस और वर्ग है:

यहाँ परिदृश्य है

public interface IInterface 
{ 
    string TestValue { get; set; } 
} 

public class RealValue: IInterface 
{ 
    public string TestValue { get; set; } 
} 

अगर मैं इस तरह की एक विधि बनाने तब भी वह अच्छे संकलित:

public class RandomTest: IMethodInterface 
{ 
    public IInterface GetRealValue() 
    { 
     RealValue realValue = new RealValue(); 
     return realValue; 
    } 
} 

ध्यान दें कि मैं कर रहा हूँ इंटरफ़ेस लागू करने वाली ऑब्जेक्ट को वापस करना।

अब, अगर मैं RandomTest वर्ग के लिए एक विधि है कि सूची लौटाती जोड़ने तो इसे अब और काम नहीं करता:

public List<IInterface> GetRealValues() 
{ 
    List<RealValue> realValues = new List<RealValue>(); 
    return realValues; // ERROR Here <- says it can't convert to a List<IInterface> 
} 

तो, मेरा अनुमान है कि जेनरिक इस को समझ नहीं सकता है, लेकिन क्यों?

क्या इसके आसपास कोई रास्ता है?

public interface IMethodInterface 
{ 
    IInterface GetRealValue(); 
    List<IInterface> GetRealValues(); // Can't just convert the return types to a concrete 
             // class because I am implementing this. This 
             // interface is in a separate project that does not 
             // have the concrete classes. 
} 

वहाँ किसी भी आशा है: आप जब विधि की वापसी मूल्य से ऊपर बंद कर दिया जाता है क्योंकि आप इस तरह एक अंतरफलक को लागू कर रहे हैं क्या करते हैं? तुम क्या करोगे?

उत्तर

9

इसका कारण यह है कि List<RealValue> एक विशिष्ट प्रकार है, जो List<IInterface> का उत्तराधिकारी नहीं है, इसलिए इसे परिवर्तित नहीं किया जा सकता है।

हालांकि, .NET 4.0 में आप भाग्यशाली हैं। इंटरफ़ेस IEnumerable<out T> निर्दिष्ट करता है कि T वर्ग, या एक आधार वर्ग हो सकता है, तो आप करने के लिए अपने-प्रक्रिया में परिवर्तन कर सकते हैं: .NET 4.0 पर

IEnumerable<IInterface> GetRealValues(); 

। ध्यान दें कि यह केवल काम करता है क्योंकि IEnumerable में टेम्पलेट पैरामीटर पर out कीवर्ड निर्दिष्ट है।

  1. प्रकार है जो इससे पहले कि आप out कीवर्ड डाल केवल प्रकार है कि कक्षा से बाहर जाने के लिए इस्तेमाल किया जा सकता है:

    out कीवर्ड दो बातें मतलब है। तो, public T MyMethod() की अनुमति है, लेकिन public void MyMethod(T myParam) की अनुमति नहीं है, क्योंकि यह कक्षा में जाता है;

  2. इस प्रतिबंध की वजह से

    , .NET जानता है कि T सब कुछ है कि T से विरासत के लिए मामलों जा सकता है। प्रतिबंध के कारण, यह एक सुरक्षित संचालन होने की गारंटी है।

+0

यह अच्छा लग रहा है। मुझे एक सामान्य प्रकार के पैरा के लिए 'आउट' का अर्थ समझने के लिए और अधिक खोदना होगा। किसी भी तरह से, मैंने कोशिश की और यह काम किया। – Vaccano

+0

'आउट' कीवर्ड से संबंधित थोड़ी अधिक जानकारी के साथ उत्तर का विस्तार किया। –

+0

मीठा! विस्तारित उत्तर के लिए धन्यवाद! – Vaccano

1

List<IInterface> के स्थान पर उपयोग नहीं किया जा सकता है। यदि इसकी अनुमति थी, तो कॉलर RealValue के अलावा किसी अन्य प्रकार की लौटाई गई सूची में IInterface जोड़ने में सक्षम होगा।

3

ध्यान दें कि यदि आप List<RealValue> से List<IInterface> पर परिवर्तित कर सकते हैं तो आप .Add(anyObjectImplementingIInterface) पर कॉल कर सकते हैं जो काम नहीं कर सकता।

हालांकि, आप .Cast<IInterface>().ToList() का उपयोग कर सकते हैं।

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