2011-08-03 108 views
0

請參閱Main()中的註釋。爲什麼我不能執行以下操作?SomeList <T>:List <T> can not be cast as List <T>?

public class SomeList<T> : List<T> 
{ 
    public SomeList(List<T> existing) 
    { 
     foreach (var item in existing) 
      Add(item); 
    } 

    public override string ToString() 
    { 
     return "I'm a better list."; 
    } 
} 

internal interface IReadStuff<T> 
{ 
    List<T> ReadStuff(); 
} 

public class ReaderStrategy<Foo> : IReadStuff<Foo> 
{ 
    public List<Foo> ReadStuff() 
    { 
     return new List<Foo>(); 
    } 
} 

public class Foo {} 

public class Main 
{ 
    public Main() 
    { 
     var reader = new ReaderStrategy<Foo>(); 

     // This works, but type is List<Foo>, not SomeList<Foo> 
     List<Foo> aList = reader.ReadStuff(); 
     // This does not compile, but is what I want to do: 
     SomeList<Foo> aBetterList = reader.ReadStuff(); 
     // This compiles, but always generates null for aBetterList: 
     SomeList<Foo> anotherBetterList = reader.ReadStuff() as SomeList<Foo>; 
     // This is funky but works: 
     SomeList<Foo> works = new SomeList<Foo>(reader.ReadStuff()); 
    } 
} 

我在努力理解如何使用泛型與繼承類型。我有一個需要上面的,因爲我想擴展功能List<T>是一些特殊的方式,例如見SomeList<T> overrides ToString()。但是,我想使用.Net通用List<T>來保持我的工廠策略。有沒有辦法做到這一點?

編輯

我補充說,接受List<T>,並增加了SomeList<T>構造。這似乎並不自然,但有效。這是一項昂貴的操作,特別是如果List<T>很大。

我的問題標題不是最好的,我努力的是一個例子,顯示了一個更好的方法來做到這一點。

+0

除了'的ToString()'我沒有看到名單''任何虛擬方法,因此繼承了它可能是通常不是一個好主意。 – BrokenGlass

回答

3

reader.ReadStuff()返回List<Foo> - 但您試圖將其分配給類型爲SomeList<Foo>的對象,該對象繼承自List<Foo>。這是行不通的,因爲List<Foo>不是SomeList<Foo> - 這是相反的。

想想看 - 這是合法的,從ReadStuff()返回List<Foo>對象 - 那麼你嘗試這種對象僅適用於SomeList<Foo>可在訪問功能 - 這將打破,這就是爲什麼OOP不允許你這樣做這個 - 一個子類的實例可以用在需要父類實例的地方 - 但是你不能在需要子類的地方使用父類。

回到你的問題標題:SomeList<T>List<T>不能被鑄造爲List<T>?是的,這是可能的,但你試圖將List<T>投到SomeList<T>

1

SomeList的所有實例都是List的實例。但是,並非List的所有實例都是SomeList的實例。這是第二項任務正在做的事情。 reader.ReadStuff()返回一個List,而不是一個SomeList。希望這可以幫助。

1

在你的例子中,你不是將SomeList<Foo>的實例投射到List<Foo>,而是試圖將List<Foo>投射到SomeList<Foo>。你從不那麼具體到更具體,這是行不通的。它應該反過來工作。

0

改變這種代碼

SomeList<Foo> aBetterList = reader.ReadStuff() 

to 
SomeList<Foo> aBetterList = reader.ReadStuff() as SomeList<Foo>; 

before using 
    if(aBetterList !=null) {} 
+0

我試過了,它總是返回null – sapbucket

相關問題