擴展方法直到3.5才被添加到.NET中。但是,這不是對CLR的更改,而是添加了它們的a change to the compiler,因此您仍然可以在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文件來使用它們。
現在,如果你想要LINQ功能,將需要一些額外的工作。您將需要自己重新實施擴展方法。爲了模擬完整的LINQ to SQL功能,代碼可能會變得非常複雜。但是,如果您只是使用LINQ to Objects,大多數LINQ方法實現起來並不複雜。這裏有幾個LINQ 到 對象替換功能,我從一個項目中寫出來讓你開始。
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;
}
}
與LINQ 的全重,以實行對象 已添加在ExtensionAttribute
庫可以在LinqBridge項目(感謝Allon Guralnek)被發現。
重要的是要指出,您的LinqReplacement方法將只適用於Linq到對象。它不適用於Linq to Sql。好像很多人沒有意識到有什麼不同。但仍然+1 – cadrell0 2012-07-05 14:46:40
您不必自己重新實施擴展方法。很久以前,[LINqBridge](http://linqbridge.googlecode.com/)已經爲.NET 2.0重新實現了完整的LINQ-to-Objects提供程序。它已經包含了'ExtensionAttribute',它允許你在.NET 2.0及以上版本的.NET 2.0中創建擴展方法。 – 2012-07-05 14:52:15
@AllonGuralnek感謝您的鏈接,更新了答案並給了您信任。 – 2012-07-05 14:56:24