5

を返すファクトリ関数がありDbSet(Of IItemType)ます。IItemTypeたとえば、実際の戻り値の型は常に実装になりますDbSet(Of CategoryType)

共分散はジェネリックでサポートされており、このメソッドは正常に機能すると思いましたが、コードを実行しようとすると例外が発生します。

タイプ 'System.Data.Entity.DbSet 1[CategoryType]' to type 'System.Data.Entity.DbSet1[IItemType]' のオブジェクトをキャストできません。

4

2 に答える 2

7

DbSet<T>共変であることはできません。まず、これは、C# では、クラスは共変ではなく、インターフェイスのみであるためです。DbSet<T>第二に、共変法と反変法の両方があるためです。

次の 2 つの例を見てみましょう。

DbSet<CategoryType> set = context.Set<CategoryType>();
IQueryable<IItemType> query = set.Where(x => x.Foo == Bar);

したがって、すべてCategoryTypeの s がIItemTypeであることがわかっているため、これは常に機能することがわかっています。

しかし逆にこれを試してみてください...

DbSet<CategoryType> set = context.Set<CategoryType>();
IItemType newItemType = new ProductType();
set.Add(newItemType);  // Compiler error.

すべてIItemTypeがであるわけではありませんCategoryType。したがって、キャストできると、追加時に実行時エラーが発生します...コンパイラは、これが常に機能するとは限らないことを認識しているため、キャストDbSet<CategoryType>DbSet<IItemType>実行できません。

DbSet<T>ただし、Co-Variance をオンにできるインターフェイスがあります。IQueryable<IItemType>たとえば、キャストしてみることができます。

ただし、インターフェイスに対するクエリを使用して DbSet に対してクエリを実行しようとしているようです...次を試してください

DbSet<CategoryType> set = context.Set<CategoryType>();
IQueryable<IItemType> cast = set.OfType<IITemType>(); //(or .Cast<>() works too)
IQueryable<IItemType> query = cast.Where(x => x ....);
于 2013-09-30T06:42:31.910 に答える