2017-09-03 56 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