我今天发现了一些重复的代码,想把它减少到一个方法。为了做到这一点,我想在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
}
我尝试使用花括号访问局部变量paramFoo,但这无法编译。
IEnumerable<AbstractFoo> exactMatchFoo = exactMatchList
.Where (d => is {paramFoo.GetType();}); //compile error
同样值得注意的是:AbstractFoo
是一个抽象类,RedFoo
和BlueFoo
都继承自它。此时我的代码中没有接口。
如何在linq的lambda表达式中捕获局部变量的类型?
使用Enumerable。查找所需类型的所有元素
OfType(IEnumerable)方法只返回源中可以转换为result类型的元素。若要在元素不能强制转换为result类型时接收异常,请使用cast (IEnumerable)。
public IEnumerable<AbstractFoo> GetMatchingFoos<T>() where T : AbstractFoo
{
return exactMatchList.OfType<T>();
}
有一个LINQ扩展方法可以按类型查找OfType<T>
。
请参阅我刚才编写的以下代码片段(您也可以在这里运行它):
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());
}
}