2

次のクラスがあります。

public class EntityBase<T>
{
    public T Id { get; set; }

}

そしてそれは実装者です:

public class ClassA : EntityBase<Int32>
{
     ...
}

public class ClassB : EntityBase<Int64>
{
     ...
}

そして、クラスについて知らないコードでは、EntityBase<...> の存在についてのみ知っているので、次のようにしますClassAClassB

     // Here for sure I get the list of `ClassA`
     object obj = GetSomeHowListOfClassA();
     List<EntityBase<Int32>> listOfEntityBases = (List<EntityBase<Int32>>)obj;

そして、私はエラーが発生します:

Unable to cast object of type 'System.Collections.Generic.List`1[...ClassA]' to type 'System.Collections.Generic.List`1[...EntityBase`1[System.Int32]]'.

私は次のように修正します:

var listOfEntityBases = new List<EntityBase<Int32>>(obj);

しかし、新しい List<> を作成しているので、この方法は好きではありません。キャストする方法はありますか?前進のためのThx。

4

2 に答える 2

2

明確な理由でそれを行うことはできません。次のコード行が機能すると仮定しましょう。

 List<EntityBase<Int32>> listOfEntityBases = (List<EntityBase<Int32>>)obj;

これは、その行の後に次のように言うことができることを意味します

listOfEntityBases.Add(new EntityBase<Int32>());

しかし、実際には、この行と同時にEntityBase<Int32>オブジェクトをobjタイプに追加します。List<ClassA>これは間違いなくInvalidCast です

したがって、同じ変数をList<ClassA>同時に宣言することはできませんList<EntityBase<Int32>>

ただし、そのようなコレクションに新しい値を追加することはできないため、簡単に許可さIEnumerable<T>れます。

そしてそれがジェネリック宣言にinandがある理由です。out

于 2013-04-04T10:43:47.710 に答える
0

次の理由により、この方法でキャストすることはできません。

  • C# の共分散はクラスでは機能しません。
  • インターフェイスIList<T>でありICollection<T>、共変ではありません。

ここでできる唯一のオプション (リストのコピーを作成することを除く) は、次のようにキャストすることIEnumerabe<T>です。

var listOfEntityBases = (IEnumerable<EntityBase<Int32>>)obj;
于 2013-04-04T10:43:38.037 に答える