¿Puedo usar métodos de extensión y LINQ en .NET 2.0 o 3.0?

Cuando trato de agregar un método de extensión usando .NET 2.0 o 3.0 runtime, obtengo el error:

No se puede definir un nuevo método de extensión porque el comstackdor requerido tipo ‘System.Runtime.CompilerServices.ExtensionAttribute’ no se puede encontrar. ¿Echas de menos una referencia a System.Core.dll?

Pero no puedo encontrar System.Core en la lista de referencias disponibles cuando bash agregarlo al proyecto. ¿Qué debo hacer para poder usar los métodos de extensión y, a su vez, LINQ en mis proyectos?

Los métodos de extensión no se agregaron a .NET hasta 3.5. Sin embargo, no fue un cambio en el CLR, sino un cambio en el comstackdor que los agregó, por lo que aún puede usarlos en sus proyectos 2.0 y 3.0. El único requisito es que debe tener un comstackdor que pueda crear proyectos de 3.5 para poder hacer esta solución (Visual Studio 2008 y superior).

El error que obtiene cuando intenta utilizar un método de extensión es engañoso, ya que realmente no necesita System.Core.dll para usar los métodos de extensión. Cuando utiliza un método de extensión, detrás de las escenas, el comstackdor agrega el atributo [Extension] a la función. Si tiene un comstackdor que entiende qué hacer con el atributo [Extension] , puede usarlo en sus proyectos 2.0 y 3.0 si usted mismo crea el atributo.

Simplemente agregue la siguiente clase a su proyecto y luego puede comenzar a usar métodos de extensión:

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

El bloque de código anterior se encuentra dentro de System.Core.Dll , por lo que el error indica que debe incluir el archivo DLL para usarlos.


Ahora, si desea la funcionalidad LINQ, necesitará un poco más de trabajo. Tendrá que volver a implementar los métodos de extensión usted mismo. Para imitar la funcionalidad LINQ to SQL completa , el código puede ser bastante complicado. Sin embargo, si solo está utilizando LINQ to Objects, la mayoría de los métodos LINQ no son complicados de implementar. Aquí hay algunas funciones de reemplazo de LINQ to Objects de un proyecto que escribí para comenzar.

 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; } } 

En el proyecto LinqBridge (Thanks Allon Guralnek ) se puede encontrar una biblioteca con la reintroducción completa de LINQ to Objects con ExtensionAttribute ya agregado.