2017-09-03 8 views
0

私は、さまざまなクラスオブジェクトを含むことができる汎用リストを持っています。 Alこれらのクラスは、Idプロパティを持つ同じ基本クラスを持っています。検索一般リスト<T> Idプロパティ

私はプロパティに取得することはできませんしかし、私は唯一の限りを取得、一覧でIDを検索を行うと、最初のoccourenceを抽出するために、この

T result = myGenericList.Where(i => i.Id == id).FirstOrDefault() 

ような何かをしたいと思います:私= > i。

EDIT: myGenericListのコードを入力するよう求められます。ここではそれが行く:

public static IEnumerable<T> Initialize() 
{ 
    List<T> allCalls = new List<T>(); 

    var phoneCalls = new PhoneCall[] 
    { 
    new PhoneCall{Id = 1, Date= DateTime.Now.AddDays(-1), DurationSec = 60, Phone = "", Region = new Country { From = "", To = ""}}, 
    ... 
    }; 
    foreach (PhoneCall s in phoneCalls) 
    { 
    allCalls.Add(s as T); 
    } 

    var dataCalls = new DataCall[] 
    { 
    new DataCall{Id = 6, WebData = 5120, Phone = "", Region = new Country { From = "", To = ""}}, 
    ... 
    }; 
    foreach (DataCall s in dataCalls) 
    { 
    allCalls.Add(s as T); 
    } 

    var smsCalls = new SmsCall[] 
    { 
    new SmsCall{Id = 6, SmsData = 512, Phone = "", Region = new Country { From = "", To = ""}}, 
    ... 
    }; 
    foreach (SmsCall s in smsCalls) 
    { 
    allCalls.Add(s as T); 
    } 

    return allCalls; 

あなたは何をすべき私はRepository.csクラスの先頭で定義したクラス

public class Repository<T> : IRepository<T> where T : class 
+0

'myGenericList' –

+1

Tが何であるの宣言を示してください?タイプTに正しくキャスティングされていますか?また、myGenericListを共有できますか? –

+0

私は、Tプロパティが定義されているT:BaseClass制約が存在しないと思います。おそらく、これはまだ一般的な入力タイプをまだ何かに制限していない拡張メソッドでした。 –

答えて

1

基本クラスにキャストしようとしましたか?

myGenericList 
    .Cast<BaseClass>() 
    .FirstOrDedault(i => i.Id === id) 

または代わり

myGenericList.FirstOrDefault(i => (i as BaseClass).Id === id) 
+1

この場合、キャストは解決策の代わりに回避策です。 –

+0

@GiladGreenかもしれませんが、OPがコードに対してどれだけの制御を行っているかによって異なります。私はそれが何であるかについて質問をしました、彼らはとして扱いたい一般的なリストを持っています。同様の問題を抱えて、他の人を導く助けとなります。 – James

+0

こんにちは、2番目のオプションはそれをしました。ありがとう – Ovis

3

はキャストTが何であるかを定義していないですTについてアイテムはTになります。コンパイラはTが何であるかを知る方法がないため、Idプロパティを持っています。そうするために、一般的な制約を使用します。

public static IEnumerable<T> Initialize<T where T : BaseClass>() 
{ 
    var allCalls = new List<T>(); 
    allCalls.Add(new PhoneCall { /* Details */}; 
    return allCalls; 
} 

質問を更新した後 - また、あなたがFirstOrDefaultオーバーロードを使用することができ、クラスの1


であることに機能の一つであることから、制約を動かします述語を取得する:

var result = myGenericList.FirstOrDefault(i => i.Id == id); 
+0

Tの混乱については申し訳ありません。 TはすでにRepository.csクラスの先頭に定義されています。私はちょうどそれのためのコードを貼り付けました。ここでそれは行く:public class Repository :IRepository ここでT:クラス – Ovis

+0

@Ovis - それは問題ではない:私はちょうどあなたのデザインについて少し考えるべきだと思う - もしこれがベースクラスから派生したオブジェクトそのクラスのジェネリック制約で指定することができます。もしそれを "オープン"にしておきたいのなら、それはリポジトリが派生したインスタンスを作成するという匂いがしていると思います。リポジトリ内から実際に型を知ることができない場合は、クエリコードが実際にその中にあるかどうかを考えてください。 –

+0

'' Repository 'でかなり一般的なfuncであると思われるものを制約することは、' 'BaseClass'から派生したこの_must_戻りデータを実装している誰かを意味します。' 'T :class')。このアプローチは、リポジトリ '_then_ constrained' Initialize'から派生した場合にのみ機能します。 'PhoneCallRepository' – James

関連する問題