如何在linq中捕获lambda表达式中局部变量的类型

时间:2015-06-05 16:31:23

标签: c# linq lambda closures abstract-class

我今天发现了一些重复的代码,并希望将其减少为一种方法。为了做到这一点,我想在这里向lambda注入一些更抽象的东西:

public IEnumerable<AbstractFoo> GetMatchingFoos()
{
     return IEnumerable<AbstractFoo> exactMatchFoo = exactMatchList
            .Where (d => d is RedFoo);
}

//Horrifying duplicate code!:
public IEnumerable<AbstractFoo> GetMatchingFoos()
{
     return IEnumerable<AbstractFoo> exactMatchFoo = exactMatchList
            .Where (d => d is BlueFoo);
}

我希望能够将RedFoo / BlueFoo替换为我可以注入的单个方法,如下所示:

public IEnumerable<AbstractFoo> GetMatchingFoos(paramFoo)
{
    IEnumerable<AbstractFoo> exactMatchFoo = exactMatchList
    .Where (d => d is paramFoo.GetType()); //compile error
}

tried using curly braces访问本地变量paramFoo,但是没有编译。

IEnumerable<AbstractFoo> exactMatchFoo = exactMatchList
.Where (d => is {paramFoo.GetType();}); //compile error

另外值得注意的是:AbstractFoo是一个抽象类,RedFooBlueFoo都继承自。{1}}。此时我的代码中没有接口。

如何在linq中的lambda表达式中捕获局部变量的类型?

2 个答案:

答案 0 :(得分:3)

使用Enumerable.OfType查找所需类型的所有元素。

  

OfType(IEnumerable)方法仅返回源中可以强制转换为TResult类型的元素。如果无法将元素强制转换为类型TResult,则使用Cast(IEnumerable)来代替接收异常。

public IEnumerable<AbstractFoo> GetMatchingFoos<T>() where T : AbstractFoo
{
    return exactMatchList.OfType<T>();
}

答案 1 :(得分:0)

可以通过名为OfType<T>的类型查找LINQ扩展方法。

请参阅我刚才制作的以下代码段(同样,you can run it here):

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public class A {}

    public class B : A {}

    public class C {}

    public static void Main()
    {
        IEnumerable<A> result = new object [] { new A(), new B(), new C() }.OfType<A>();

            // Result: 2, because there're two instance of type A!
        Console.WriteLine(result.Count());
    }
}