Metode ekstensi tidak ditambahkan ke .NET hingga versi 3.5. Namun, hal tersebut bukanlah perubahan pada CLR, melainkan perubahan pada kompiler yang menambahkannya, sehingga Anda masih dapat menggunakannya di proyek 2.0 dan 3.0 Anda! Satu-satunya persyaratan adalah Anda harus memiliki kompiler yang dapat membuat 3,5 proyek untuk dapat melakukan solusi ini (Visual Studio 2008 ke atas).
Kesalahan yang Anda dapatkan saat mencoba menggunakan metode ekstensi menyesatkan karena Anda tidak benar-benar memerlukan System.Core.dll
untuk menggunakan metode ekstensi. Saat Anda menggunakan metode ekstensi, di belakang layar, kompiler menambahkan [Extension]
ke fungsi. Jika Anda memiliki kompiler yang memahami apa yang harus dilakukan dengan atribut [Extension]
, Anda dapat menggunakannya di proyek 2.0 dan 3.0 jika Anda membuat atribut sendiri.
Cukup tambahkan kelas berikut ke proyek Anda dan Anda kemudian dapat mulai menggunakan metode ekstensi:
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class ExtensionAttribute : Attribute
{
}
}
Blok kode di atas berada di dalam System.Core.Dll, itulah sebabnya kesalahan mengatakan Anda perlu menyertakan file DLL untuk menggunakannya.
Sekarang jika Anda menginginkan fungsionalitas LINQ itu akan membutuhkan sedikit kerja ekstra. Anda perlu menerapkan kembali metode penyuluhan sendiri. Untuk meniru fungsionalitas penuh LINQ ke SQL, kodenya bisa menjadi cukup rumit . Namun, jika Anda hanya menggunakan LINQ to Objects sebagian besar metode LINQ adalah tidak rumit untuk diterapkan. Berikut adalah beberapa fungsi pengganti LINQ ke Objek dari proyek yang saya tulis untuk membantu Anda memulai.
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;
}
}
Pustaka dengan implementasi ulang penuh LINQ ke Objek dengan ExtensionAttribute
yang sudah ditambahkan dapat ditemukan di Proyek LinqBridge (Terima kasih Allon Guralnek).
person
Scott Chamberlain
schedule
05.07.2012