2011-07-01 14 views
5

拡張メソッドは内部でどのように実装されていますか?私は、コンパイラが拡張メソッドの宣言を見ているときに何が起こるのかと、拡張メソッドへの呼び出しがあるときに実行時に何が起こるのかを意味します。内部で拡張メソッドを実装する方法

反射が関与していますか?または、拡張メソッドがある場合、拡張メソッドであることに注目して、いくつかの追加フラグを指定してターゲットクラスのメタデータにコードを挿入し、CLRでそれを処理する方法を知っていますか?

一般に、フードの下ではどうなりますか?

答えて

6

は、すでに述べたように、それは単なる静的メソッドである他の同僚で述べています。 CLRは拡張メソッドについても全く知らないと言うことができます。 あなたはここに

を例

static class ExtendedString 
{ 
    public static String TestMethod(this String str, String someParam) 
    { 
     return someParam; 
    } 
} 

static void Main(string[] args) 
{ 
    String str = String.Empty; 
    Console.WriteLine(str.TestMethod("Hello World!!")); 
    ........ 
} 

であり、ここでILコード..ですILコードをチェックしてみてください。

IL_0001: ldsfld  string [mscorlib]System.String::Empty 
    IL_0006: stloc.0 
    IL_0007: ldloc.0 
    IL_0008: ldstr  "Hello World!!" 
    IL_000d: call  string StringPooling.ExtendedString::TestMethod(string, 
                     string) 
    IL_0012: call  void [mscorlib]System.Console::WriteLine(string) 
    IL_0017: nop 

これは静的メソッドの呼び出しです。 メソッドはクラスに追加されませんが、コンパイラはそのように見えます。 反射層の違いは、コンパイラサービスだけです。ExtensionAttributeが追加されました。

4

拡張メソッドは静的functions.In他の言葉に変換され、彼らは静的関数のシンタックスシュガーです。

2

私はreflectionが拡張メソッドに関与していることと思ういけません。拡張メソッドは、helper classstatic helper functionと書くのと同じ方法で処理されますが、唯一の違いはコンパイラがそれを行う点です。

1

上記の答えを明確にするには...拡張メソッドは静的関数です。 .NET 3.5の追加機能により、問題のタイプの新しいメソッドであるかのように解釈されます。

0

拡張メソッドは静的メソッドです。唯一の違いは、Visual Studioエディタなどの自動完成(インテリセンス)機能用にポップアップするツールによってもたらされます。あなたはここに詳細な説明を見つけることができます:C# Extension Methods: Syntactic Sugar or Useful Tool?

0

拡張メソッドは、非常に多くの拡張メソッドとしてそれを識別するのに役立ちます属性CompilerServices.ExtensionAttributeを持つことの唯一の違いとstatic方法などがあります。

あなたはread this

0

はい、拡張メソッドは静的なメソッドですできます。彼らは彼らが「拡張する」クラスに対して特別な特権を持っていません。ただし、コンパイラはExtensionAttributeを使用して "拡張"静的メソッドにマークを付けます。これはILで見ることができます。これにより、コンパイラは特別に扱うので、通常の静的メソッドとして呼び出すことはできません。たとえば、これはコンパイルされません:

var test = new [] { "Goodbye", "Cruel", "World" }; 
var result = IEnumerable<string>.Where<string>(test, s => s.Length > 5); 

これは、ボンネットの下で起こるものですが。

しかしLukeHは、以下の注意事項として、あなたはそれが実際に...愚かな私に定義されていたクラスでそれを呼び出すことができます。

+0

拡張メソッドを直接静的メソッドとして呼び出すことができます。静的メソッドは、静的な別のクラスの静的メソッドです: 'var result = Enumerable.Where (test、s => s.Length> 5); ' – LukeH

+0

'絶対に正しい。あなたが「拡張している」タイプからそれを呼び出そうとするのは理にかなっていません。私の悪い。 – Einar

関連する問題