2016-06-20 9 views
4

私はDbContextクラスを持っています。たとえば:c#ジェネリックのためにこのクラスを使用する

class Contact extends DbContext {} 

クラスDbContextの中では、私はジェネリックでDbContextを拡張する方クラスを使用します:

public static IEnumerable<DBContext> GetAll() 
    { 
     var sql = "SELECT * FROM " + TableName(); 
     return DB().Fetch<DBContext> (sql); 
    } 

注IEnumerableを< DBContext>ここに。

上記のコードは問題ありませんが、毎回タイプキャストする必要があります。

public static IEnumerable<thisClass> GetAll() 
{ 
    var sql = "SELECT * FROM " + TableName(); 
    return DB().Fetch<thisClass> (sql); 
} 

注IEnumerableを< thisClass>ここに:私のようなものthisClassを達成することができます。 DStanleyさんのコメントの後

public static IEnumerable<T> GetAll<T>() 
    { 
     var sql = "SELECT * FROM " + TableName(); 

     return DB().Fetch<T> (sql); 
    } 

しかし、私はこのように呼び出すにしたくない:

私が実行しようとしました

Contact.GetAll<Contact>(); 

ないきれい。右?

注:TableName()はここで心配するものではありません。それは、それが呼び出されるクラスに基づいて私の方法でSQLメソッドを取得します。

+3

「public static IEnumerable GetAll ()ここでT:DbContext'と宣言し、ウサギの穴までの距離を確認してください。 'TableName()'が何をするのか、またそれが汎用的である必要があるのか​​は不明です。 –

+4

またはhttps://en.wikipedia.org/wiki/Curiously_recurring_template_pattern – SLaks

+0

@Dスタンリーを使用してください。私は実際に行ったが、毎回クラスに合格したくない。私はそれについて私の質問を更新します。 – tika

答えて

4

再帰的なジェネリック制約を設定することで、作業を進めることができます。

まず、汎用DbContext<T>DbContextを汎用に変更するか、継承レイヤーを追加する)が必要です。内部では、あなたの方法を定義します。次に

public class DbContext<T> : DbContext 
{ 
    public static IEnumerable<T> GetAll() 
    { 
     var sql = "SELECT * FROM " + TableName(); 

     return DB().Fetch<T> (sql); 
    } 
} 

ジェネリッククラスからあなたの子供DbContext継承させる:

public class Contact : DbContext<Contact> 
{ 

} 

今、あなたはContact.GetAll();を書くことができます。

+0

@Kookoz、今はそれが最高です。 – tika

+0

勝利のためのF-bound多型。 –

0

あなたはジェネリック型Tとしてクラス・パラメータに名前を付けて、それはそうのように実装する必要があるもののインターフェイス名前を付けることができます:あなたがいる限り、それは実装して、あなたの方法に任意のクラスを渡すことができます。これにより

public static IEnumerable<T> GetAll() where T : DBContext 
    { 
    var sql = "SELECT * FROM " + TableName(); 
    return DB().Fetch<DBContext> (sql); 
    } 

をあなたのDBContextインターフェイス

MSDNでhereをもっと読むことができます。

編集:コメントのD Stanleyが言ったことを見なかった - これは彼の解決策でもある。

+0

そのバディを試してみました。ありがとうございます。しかし、Person.GetAll ()のように、そのメソッドを別のクラスから呼び出す方法を提案しても、それは非常にきれいではありません。人を2回書く。 – tika

1

この呼び出しの結果をタイプIEnumerable<Contact>の変数に代入する場合は、正しいメソッドを呼び出す必要があります。

が有効です。

+0

はい、あります。しかし、それは型キャストです。私は私の質問で言及した。ありがとうございました。でも、それは私が気に入っているものではありません。また、私はここでメソッドをチェーンすることはできません – tika

+0

私は...どのメソッドも連鎖していません。 –

+0

これは、タイプキャストではなく、実行時に行うものです。これは、ターゲット変数のヒントに基づいてメソッドを理解するコンパイラです。 –

関連する問題