Erweiterungsmethoden wurden bis 3.5 nicht zu .NET hinzugefügt. Es war jedoch keine Änderung an der CLR, sondern a change to the compiler, die sie hinzugefügt hat, so dass Sie sie immer noch in Ihren 2.0 und 3.0 Projekten verwenden können! Die einzige Voraussetzung ist, dass Sie einen Compiler haben müssen, der 3.5 Projekte erstellen kann, um diese Problemumgehung zu ermöglichen (Visual Studio 2008 und höher).
Der Fehler, den Sie erhalten, wenn Sie eine Erweiterungsmethode, wie Sie System.Core.dll
nicht wirklich irreführend zu verwenden versuchen müssen Erweiterungsmethoden verwenden. Wenn Sie im Hintergrund eine Erweiterungsmethode verwenden, fügt der Compiler der Funktion das Attribut [Extension]
hinzu. Wenn Sie einen Compiler haben, der versteht, was mit dem Attribut [Extension]
zu tun ist, können Sie es in Ihren 2.0- und 3.0-Projekten verwenden, wenn Sie das Attribut selbst erstellen.
Fügen Sie einfach die folgende Klasse zu einem Projekt und Sie können dann Erweiterungsmethoden beginnen mit:
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class ExtensionAttribute : Attribute
{
}
}
Der obige Codeblock innerhalb System.Core.Dll sitzt, so dass ist, warum der Fehler sagt müssen Sie die DLL enthalten Datei, um sie zu verwenden.
Jetzt, wenn Sie LINQ-Funktionalität möchten, die ein wenig mehr Arbeit benötigen. Sie müssen die Erweiterungsmethoden selbst erneut implementieren. Um die volle LINQ to SQL Funktionalität nachzuahmen, kann der Code ziemlich kompliziert werden. Wenn Sie jedoch nur LINQ to Objects verwenden, sind die meisten LINQ-Methoden nicht kompliziert zu implementieren. Hier sind ein paar LINQ zu Objects Ersatzfunktionen aus einem Projekt, das ich ausschrieb, um loszulegen.
public static class LinqReplacement
{
public delegate TResult Func<T, TResult>(T arg);
public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
public static TSource First<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> 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<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
throw new ArgumentNullException("source");
foreach (TSource item in source)
{
return item;
}
return default(TSource);
}
public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source)
{
foreach (object item in source)
{
yield return (TResult)item;
}
}
public static IEnumerable<TResult> SelectMany<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> 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<TSource>(this IEnumerable<TSource> 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;
}
}
Eine Bibliothek mit der vollen Wieder Implemenation von LINQ - Objekten mit den ExtensionAttribute
bereits hinzugefügt kann im LinqBridge Projekt gefunden werden (Danke Allon Guralnek).
Es ist wichtig darauf hinzuweisen, dass Ihre LinqReplacement-Methoden nur für Linq to Objects funktionieren. Es wird nicht funktionieren für Linq zu Sql. Es scheint, als würden viele Leute nicht erkennen, dass es einen Unterschied gibt. Aber immer noch +1 – cadrell0
Sie müssen die Erweiterung Methoden nicht erneut implementieren. Der vollständige LINQ-to-Objects-Provider wurde bereits vor langer Zeit als [LinqBridge] (http://linqbridge.googlecode.com/) für .NET 2.0 neu implementiert. Und es enthält bereits das ExtensionAttribute, mit dem Sie Erweiterungsmethoden in .NET 2.0 mit VS 2008 und höher erstellen können. –
@AllonGuralnek Danke für den Link, aktualisiert die Antwort und gab Ihnen Kredit. –