我可以在.NET 2.0或3.0中使用扩展方法和LINQ吗?

当我尝试使用.NET 2.0或3.0运行时添加扩展方法时,我收到错误:

无法定义新的扩展方法,因为无法找到编译器所需的类型“System.Runtime.CompilerServices.ExtensionAttribute”。 您是否缺少对System.Core.dll的引用?

但是当我尝试将它添加到项目中时,我无法在可用引用列表中找到System.Core。 我需要做什么才能在我的项目中使用扩展方法和LINQ on?

直到3.5才将扩展方法添加到.NET。 但是,它不是对CLR 的更改 ,而是对添加它们的编译器的更改 ,因此您仍然可以在2.0和3.0项目中使用它们! 唯一的要求是您必须具有可以创建3.5个项目的编译器才能执行此解决方法(Visual Studio 2008及更高版本)。

尝试使用扩展方法时出现的错误是误导性的,因为您并不真正需要System.Core.dll来使用扩展方法。 在后台使用扩展方法时,编译器会将[Extension]属性添加到函数中。 如果您有一个能够理解如何处理[Extension]属性的编译器,那么如果您自己创建属性,则可以在2.0和3.0项目中使用它。

只需将以下类添加到项目中,然后就可以开始使用扩展方法:

 namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] public class ExtensionAttribute : Attribute { } } 

上面的代码块位于System.Core.Dll中 ,因此错误说您需要包含DLL文件才能使用它们。


现在,如果你想要LINQfunction,需要额外的工作。 您需要自己重新实现扩展方法。 为了模仿完整的LINQ to SQLfunction,代码可能变得非常复杂。 但是,如果您只是使用LINQ to Objects,则大多数LINQ方法实现起来并不复杂。 以下是我编写的一个项目中的一些LINQ to Objects替换函数,以帮助您入门。

 public static class LinqReplacement { public delegate TResult Func(T arg); public delegate TResult Func(T1 arg1, T2 arg2); public static TSource First(this IEnumerable source, Func predicate) { if (source == null) throw new ArgumentNullException("source"); if (predicate == null) throw new ArgumentNullException("predicate"); foreach (TSource item in source) { if (predicate(item) == true) return item; } throw new InvalidOperationException("No item satisfied the predicate or the source collection was empty."); } public static TSource FirstOrDefault(this IEnumerable source) { if (source == null) throw new ArgumentNullException("source"); foreach (TSource item in source) { return item; } return default(TSource); } public static IEnumerable Cast(this IEnumerable source) { foreach (object item in source) { yield return (TResult)item; } } public static IEnumerable SelectMany(this IEnumerable source, Func> selector) { if (source == null) throw new ArgumentNullException("source"); if (selector == null) throw new ArgumentNullException("selector"); foreach (TSource item in source) { foreach (TResult subItem in selector(item)) { yield return subItem; } } } public static int Count(this IEnumerable source) { var asCollection = source as ICollection; if(asCollection != null) { return asCollection.Count; } int count = 0; foreach (TSource item in source) { checked //If we are counting a larger than int.MaxValue enumerable this will cause a OverflowException to happen when the counter wraps around. { count++; } } return count; } } 

可以在LinqBridge项目中找到一个完整重新实现LINQ to Objects且ExtensionAttributeExtensionAttribute的库 (感谢Allon Guralnek )。