1

私はより複雑な継承構造とジェネリックを理解しようとしており、このスーツに従っている現在のプロジェクトのアーキテクチャを作成しようとしています。私の問題は現在、次のエラーが発生していることです。

型引数 'Foo' は、制約型 '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> { }

上記のエラーが発生するのFooを渡そうとすると、 is aおよびis のタイプであるため、必然的にthis を実行できると思いました。TListHandlerFooList<ItemBase>FooItemItemBasevar handler = new ListHandler<Foo>();

なぜ私がこれを行うことができないのか、または私が間違っていることを誰かが説明できますか?

4

2 に答える 2

4

AListBase<ItemBase>は a と同じではありませんListBase<FooItem>特に、任意の種類のを に
追加できます。ItemBaseListBase<ItemBase>

2 つの汎用パラメーターを受け入れる必要があります。

public class ListHandler<TList, TItem> where T : ListBase<TItem> where TItem : ItemBase { }
于 2012-10-29T15:21:24.543 に答える
0

リスト タイプではなく、アイテムタイプのタイプ パラメータを指定する必要があります。これを明確にするために、ListHandlerクラスを拡張して、アイテムをインスタンスAddItemに追加するメソッドを含めてみてください。ItemBaseListBase

// 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());
于 2012-10-29T16:02:29.523 に答える