我想在我的库中添加 LINQ 支持,这样我就可以像使用 System.Xml
一样对它使用类似查询的 SQL。我该怎么做?
只是意味着使用正确的签名实现 LINQ 期望存在的方法,例如 Where
或 Select
。尽管人们普遍认为,您不必为类实现 IEnumerable
接口来支持 LINQ。但是,实现 IEnumerable
将自动免费获得 Enumerable
类上的整组 LINQ 方法,只需实现GetEnumerator
和IEnumerator
类。
在我的博客上有几个关于如何实现IEnumerable
的例子,在这篇关于迭代器模式的文章中。
但是,如果类可枚举没有意义,则无需这样做。您只需直接实现相应的 LINQ 方法。LINQ 实际上并不关心如何定义方法,只要 C# 编译即可。也就是说,如果你写:
from p in myPlist where p.Thing == "Thing" select p;
C# 编译器将其转换为:
mpPlist.Where(p => p.Thing == "Thing").Select(p => p);
只要编译,LINQ 就可以工作。若要查看方法的正确签名,请查看 MSDN 文档的 LINQ 查询方法列表。例如(假设您的PList
是PListItem
的列表):
public class PList
{
public IEnumerable<PListItem> Where(Func<PListItem, bool> predicate)
{
foreach (var item in this.items)
{
if (predicate(item))
{
yield return item;
}
}
}
}
虽然以这种方式直接实现 LINQ 可以更好地控制它的行为方式,但要正确实现它需要做很多工作,并且您需要了解返回值的含义,以及链接 LINQ 调用等。一般来说,如果你能让你的类实现IEnumerable
,让 C# 为你完成所有工作,事情就会容易得多。
必须先实现 IEnumerable。先读一读 - http://msdn.microsoft.com/en-us/library/9eekhta0.aspx
由于 LINQ to 对象适用于从IEnumerable<t>
继承的任何类,因此通过在类中继承该接口并定义 GetEnumerable 方法就足够了。
以下链接解释了如何实现 IEnumerable 接口(虽然它没有提到 LINQ,但它可以工作):http://codebetter.com/davidhayden/2005/03/08/implementing-ienumerable-and-ienumerator-on-your-custom-objects/