2016-10-12 2 views
1

C#で次のコードを書く方法はありますか?C#ジェネリック型を別のクラスに渡す方法

public T GetRandomRecord<T>(DbSet<T> set) 
{ 
    return set.OrderBy(r => Guid.NewGuid()).FirstOrDefault(); 
} 

それは私に次のエラーを与える:

Error CS0452 The type 'T' must be a reference type in order to use it as parameter 'TEntity' in the generic type or method 'DbSet'

DbSetMicrosoft.EntityFrameworkCore.DbSetです。

どうすれば修正できますか?

答えて

7

generic type constraintを試してください。この文脈におけるclassは、Tを参照型に制約する。 DateTimeは構造体なので、発信者はGetRandomRecord<DateTime>(dbSet)に電話をかけることはできません。これはコンパイラによって強制されます。

public T GetRandomRecord<T>(DbSet<T> set) where T : class 
{ 
    // ... stuff 
} 

DBSet<TEntity>が同じ制約があるため、これが必要とされています

public class DbSet<TEntity> 
    : DbQuery<TEntity>, 
     IDbSet<TEntity>, 
     IQueryable<TEntity>, 
     IEnumerable<TEntity>, 
     IQueryable, 
     IEnumerable 
     where TEntity : class 
    // M... O... U... S... EEEEE.... 
{ 

あなたはDbSetというその制約を尊重することを保証できるようになるまで、だから、コンパイラは、あなたがやっている何をさせません持っている。独自のメソッドに同じ制約を適用することで、その保証を提供することができます。これは、コンパイラにあなたを残して、代わりにあなたの呼び出し側でその謎めいたエラーメッセージを吐き出すように指示します。

+0

に制約を追加します。そして、なぜそれが必要か? – FrozenHeart

+1

@FrozenHeartこの場合、おそらく 'DbSet 'はそれ自身の型パラメータ 'T'に同じ制約を持っているからです。 –

+2

@FrozenHeartええ、私はちょうどチェックし、それは同じ制約があります。 'where TEntity:class' –

1

は、あなたの方法

public T GetRandomRecord<T>(DbSet<T> set) where T : class 
+0

それはなぜ必要なのですか? – FrozenHeart

+0

上記のEdのコメントに加えて、制約をクラスに制限すると、メソッドはこの場合に必要な参照型のみを許可することを意味します - 参照:http://stackoverflow.com/a/38483145/2779990 –

関連する問題