从基本元素列表中提取派生元素

时间:2009-06-26 06:17:27

标签: c# linq

我有一个接口列表,用于存储从该接口派生的各种对象。我想写一个函数,其中调用者指定要提取的类型。我试过这个:

List<IParts> PartList;

...

public List<IPart> Fetch(Type PartType)
{
   return this.PartList.OfType<PartType>().Cast<IPart>().ToList();
}

但它不喜欢传递类型。有什么建议吗?

2 个答案:

答案 0 :(得分:2)

将其指定为类型参数:

public List<IPart> Fetch<T>() where T : IPart
{
    return this.PartList.OfType<T>().Cast<IPart>().ToList();
}

你会这样称呼它:

List<IPart> foo = parts.Fetch<Exhaust>();

如果您在编译时知道零件类型,那就没问题。如果不这样做,则需要使用反射来基本获取OfType()中的Enumerable<T>方法,并从中创建write泛型方法。类似的东西:

private static readonly MethodInfo OfTypeMethod = 
    typeof(Enumerable).GetMethod("OfType");

public List<IPart> Fetch(Type partType)
{
    MethodInfo method = OfTypeMethod.MakeGenericMethod(partType);
    IEnumerable enumerable = (IEnumerable) method.Invoke
        (null, new object[] { PartList });
    return enumerable.Cast<IPart>().ToList();
}

答案 1 :(得分:2)

如果必须在运行时支持各种类型(而不是在编译时使用泛型):

public List<IPart> Fetch(Type PartType)
{
    if (!typeof(IPart).IsAssignableFrom(PartType))
    {
        throw new ArgumentOutOfRangeException("PartType", "Must derive from IPart");
    }
    return this.PartList.Where(i => i != null && PartType.IsAssignableFrom(i.GetType())).ToList();
}