Sco*_*ain 13 .net c# extension-methods .net-3.0 .net-2.0
当我尝试使用.NET 2.0或3.0运行时添加扩展方法时,我收到错误:
无法定义新的扩展方法,因为无法找到编译器所需的类型"System.Runtime.CompilerServices.ExtensionAttribute".您是否缺少对System.Core.dll的引用?
但是当我尝试将它添加到项目中时,我无法在可用引用列表中找到System.Core.我需要做什么才能在我的项目中使用扩展方法和LINQ on?
Sco*_*ain 28
直到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
{
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码块位于System.Core.Dll中,因此错误说您需要包含DLL文件才能使用它们.
现在,如果你想要LINQ功能,需要额外的工作.您需要自己重新实现扩展方法.为了模仿完整的LINQ to SQL功能,代码可能变得非常复杂.但是,如果您只是使用LINQ to Objects,则大多数LINQ方法实现起来并不复杂.以下是我编写的一个项目中的一些LINQ to Objects替换函数,以帮助您入门.
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;
}
}
Run Code Online (Sandbox Code Playgroud)
ExtensionAttribute在LinqBridge项目中可以找到一个完全重新实现LINQ to Objects 的库(感谢Allon Guralnek).
| 归档时间: |
|
| 查看次数: |
3164 次 |
| 最近记录: |