2012-07-05 37 views
13

私は、.NET 2.0または3.0ランタイムを使用して拡張メソッドを追加しようとすると、私はエラーを取得:.NET 2.0または3.0で拡張メソッドとLINQを使用できますか?

Cannot define a new extension method because the compiler required type 'System.Runtime.CompilerServices.ExtensionAttribute' cannot be found. Are you missing a reference to System.Core.dll?

しかし、私はしようとしたとき、私は利用可能な参照のリストにSystem.Coreを見つけることができませんそれをプロジェクトに追加します。拡張メソッドを使用できるようにするためには何が必要なのですか?また、私のプロジェクトでLINQがオンになっていますか?

答えて

28

拡張メソッドは3.5まで、.NETに追加されませんでした。しかし、それはCLRの変更ではありませんでしたが、それらを追加したa change to the compilerは、あなたの2.0と3.0プロジェクトで引き続き使用することができます!唯一の要件は、あなたがこの回避策(上記のVisual Studioの    2008)を行うことができるように3.5のプロジェクトを作成することができ、コンパイラを持っている必要があります。あなたが本当に拡張メソッドを使用するSystem.Core.dllを必要としないよう、あなたが拡張メソッドを使用しようとすると、あなたが得る

エラーが誤解を招くおそれがあります。拡張メソッドを使用すると、コンパイル時にコンパイラが[Extension]属性を関数に追加しています。 [Extension]属性を使って何をするのかを理解しているコンパイラを使用している場合は、属性を自分で作成した場合は2.0および3.0プロジェクトで使用できます。

はちょうどあなたのプロジェクトに次のクラスを追加し、その後、拡張メソッドを使用して起動することができます。

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

上記のコードブロックでエラーが言う理由があるので、あなたはDLLを含める必要があり、System.Core.Dllの内側に座っていますファイルを使用します。


LINQ機能を使用する場合は、少し余計な作業が必要になります。自分で拡張メソッドを再実装する必要があります。完全なLINQ to SQL機能を模倣するために、コードはかなり複雑になることがあります。しかし、単にLINQ to Objectsを使用している場合、ほとんどのLINQメソッドは実装するのが複雑ではありません。ここにいくつかのLINQ  から までのプロジェクトがあります。すでに追加ExtensionAttributeと オブジェクトへのLINQ  の完全な再implemenationと

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

ライブラリがLinqBridgeプロジェクト(感謝Allon Guralnek)で見つけることができます。

+0

あなたのLinqReplacement方法が唯一のオブジェクトへのLINQのために働くことを指摘することは重要です。 Linq to Sqlでは動作しません。多くの人が違いがあるとは思わないようです。しかしまだ+1 – cadrell0

+0

あなた自身で拡張メソッドを再実装する必要はありません。完全なLINQ-to-Objectsプロバイダは、LinqBridge(http://linqbridge.googlecode.com/)として.NET 2.0のために既に再実装されています。また、すでにExtensionAttributeが含まれています。これにより、.NET 2.0でVS 2008以上の拡張メソッドを作成することができます。 –

+0

@AllonGuralnekリンクをありがとう、答えを更新し、あなたに信用を与えた。一部は本当だ、あなたはまだ 'しばらく(reader.Read())収量BuildObject(リーダー)'行うADO.NETへの呼び出しでそれを使用することができますcadrell0 @ –

関連する問題