2017-09-03 41 views
0

我有一個通用列表可以包含不同的類對象。這些類具有相同的具有Id屬性的基類。搜索通用列表<T>爲Id屬性

我願做此ID在列表中搜索和提取第一occourence,像這樣

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

但是我不能去的屬性,我只得到儘可能爲:I = >我。

編輯: 我被要求提供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; 

關於第t是

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

請出示的'myGenericList' –

+1

什麼是T中的聲明?它是否正確轉換爲T型?你也可以請分享myGenericList? –

+0

我猜T缺少T:BaseClass約束,它定義了Id屬性。也許這是一種擴展方法,它尚未將通用輸入類型限制爲任何東西。 –

回答

1

你有沒有試過轉換到基類?

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

或可替代

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

我認爲這種情況下演員陣容是一種解決方法,而不是解決方案 –

+0

@GiladGreen可能,但取決於OP對代碼的控制程度。我就這個問題提出了問題,他們有一個他們想要視爲的通用列表。如果他們遇到類似問題,也可以幫助引導其他人。 – James

+0

嗨第二個選擇做到了。謝謝 – Ovis

3

你應該做的是定義什麼是T和不投,我在我的Repository.cs類的頂部定義一個類該項目到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超載那得到一個謂詞:

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

我對T混淆抱歉。 T已經在Repository.cs類的頂部定義了。我只是做了粘貼代碼。這裏是:public class Repository :IRepository 其中T:class – Ovis

+0

@Ovis - 它不是問題:)我只是覺得你應該考慮一下你的設計 - 如果這是一個專門用於從基類派生的對象的存儲庫那麼你可以在類的通用約束中指定它。如果你想保持它「開放」,那麼我認爲存儲庫將創建派生的實例是有點味道。如果你真的不知道存儲庫中的類型,那麼就應該考慮查詢代碼是否應該在其中。 –

+0

不相信這個tbh,在'Repository '上約束似乎是一個相當普遍的func意味着任何人實現這個從BaseClass派生的_must_返回數據 - 我認爲這不會是期望的行爲(基於'T :class')。如果你從'Repository '_then_ constrained'Initialize'例如'PhoneCallRepository' – James