2012-10-29 53 views
1

繼承我試圖去用更復雜的繼承結構和泛型交手,我試圖創建這是繼該套裝目前的一個項目的一些架構的對象。我的問題是目前我得到這個錯誤:麻煩鑄造從通用基礎

Type argument 'Foo' does not inherit from or implement the constraint type 'ListBase'

public class ItemBase {} 
    public class ListBase<T> where T : ItemBase 
    { 
    public virtual List<T> ListExample {get; set; } 
    } 

這些都是我的基類,儘管他們可能沒有適當命名我剛纔想顯示什麼,我想實現一個簡單的例子。

public class FooItem : ItemBase { } 
    public class Foo : ListBase<FooItem> 
    { 
    public override List<FooItem> ListExample { get; set;} 
    } 

因此,我可以擴展列表的初始基類,並做更多的事情,但我想要一個處理所有這些類的通用方法。

public class ListHandler<T> where T : ListBase<ItemBase> { } 

當我嘗試通過FooTListHandler我收到提到的錯誤,我認爲這不可避免地因爲Foo是一個List<ItemBase>FooItemItemBase類型的我能做到這一點var handler = new ListHandler<Foo>();

任何人可以解釋爲什麼我不能做到這一點還是什麼,我做錯了什麼?

回答

4

ListBase<ItemBase>是不一樣的一個ListBase<FooItem>
特別是,你可以添加任何種ItemBaseListBase<ItemBase>

你需要接受兩個通用的參數:

public class ListHandler<TList, TItem> where T : ListBase<TItem> where TItem : ItemBase { } 
+0

因此,即使'FooItem'是一個'ItemBase'我不能這樣做呢?我可以添加'ItemBase'到'列表' – LukeHennerley

+0

@LukeHennerley:錯誤的;你不能添加一個'ItemBase'到'List '。 – SLaks

+0

對不起,我明白你的意思,知道只是忘了 - 我一直在做今天這麼多的通用的變通,這已經拋出我送行課程,但感謝解釋我在做什麼錯了:) – LukeHennerley

0

您需要提供項目類型的類型參數,而不是列表類型。爲了澄清這一點,嘗試擴大ListHandler類包括AddItem方法增加了一個ItemBase項目的ListBase實例:

// As is: Won't work, because there is no way to refer to the constructed 
// specific type of ItemBase: 
public class ListHandler<TList> where TList: ListBase { 
    public TList List { get; private set; } 
    public ListHandler(TList List) { this.List = List; } 
    public void AddItem(T???? item) { List.ListExample.Add(item); } 
} 

// Corrected: this will work because TItem can be used to constrain 
// the constructed ListBase type as well: 
public class ListHandler<TItem> where TItem : ItemBase { 
    public ListBase<TItem> List { get; private set; } 
    public ListHandler(ListBase<TItem> List) { this.List = List; } 
    public void AddItem(TItem item) { List.ListExample.Add(item); } 
} 

// And this will work just fine: 
var handler = new ListHandler<FooItem>(new FooList());