2010-10-31 186 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關鍵字。

out關鍵字意味着兩件事情:

  1. 你把out關鍵字這之前的類型只能用於該出去之類的類型。因此,public T MyMethod()是允許的,但不允許public void MyMethod(T myParam),因爲這進入了類;

  2. 由於這個限制,.NET知道T可以包含從T繼承的所有內容。由於限制,這是一個安全的操作。

+0

這看起來不錯。我將不得不深入瞭解'out'對於泛型類型參數的含義。無論哪種方式,我嘗試過,它的工作。 – Vaccano 2010-10-31 07:22:14

+0

擴展了關於'out'關鍵字的更多信息。 – 2010-10-31 07:31:22

+0

甜!感謝您的擴展答案! – Vaccano 2010-10-31 18:14:40

1

A List<RealValue>不能用於代替List<IInterface>。如果允許,主叫方將能夠將IInterface添加到RealValue以外的類型的返回列表中。

3

請注意,如果您可以將List<RealValue>轉換爲List<IInterface>,則可以撥打.Add(anyObjectImplementingIInterface),這樣就無法工作。您可以使用.Cast<IInterface>().ToList()

相關問題