2012-04-04 10 views
9
public static class MyClass 
{ 
    public static void Print<T>(this T theObject) 
    { 
     Console.WriteLine("The print output is " + theObject.ToString()); 
    } 
} 

私はthisキーワードで拡張する型としてジェネリックを指定しました。コンパイル時まで型の定義が遅れてしまったので、intellisense(と何か関係するもの)はどのような型を拡張しているのですか? C#はデフォルトではトップレベルSystem.Objectになっていますか?ジェネリック拡張メソッドを作成するときに何を拡張していますか?

+2

LINQとは何が関係していますか? – BoltClock

+0

@ BoltClock'saUnicorn linqの流暢なsytnaxは拡張メソッドに基づいています。 –

+2

@ RoINamir LINQが拡張メソッドに基づいているという事実は、すべての拡張メソッドLINQを関連付けるわけではありません。 – Servy

答えて

1

コンパイル時まで型の定義が遅れているので、intellisense(と何か関係するもの)はどのように拡張していますか? C#はデフォルトでSystem.Objectのトップレベルに設定されていますか?

System.Objectの拡張であると言われるものは間違っています。 1つは、このメソッドはボックス値の入力を行いませんが、System.Objectに定義されている拡張メソッドが適用されます。

定義した拡張メソッドは、一般的にパラメータ化された拡張メソッドです。ジェネリック型パラメータとして有効な任意のタイプに適用できます。

拡張メソッドについて次のように考えていないのであれば、これを少し良く理解するのに役立ちます。拡張メソッドは、言語仕様が私たちを取り除くことを可能にするトリックです。拡張メソッドは、実際にインスタンスメソッドであるかのように呼び出すことができる静的クラスの静的メソッドです。したがって

static class Foo { 
    public static void M(this object obj) { } 
} 

は静的クラスの単なる静的メソッドです。

Foo.M(obj); 

が、我々はそれがインスタンスメソッドだようにそれを呼び出すことができます:あなたはこのようにそれを呼び出すことができますこのように

obj.M(); 

、あなたは一般的な拡張メソッドを持っている場合、分停止し、それについて考えます静的クラスの静的メソッド

static class Foo { 
    public static void M<T>(this T obj) { } 
} 

としてあなたはこのようにそれを呼び出すことができます。

object obj; 
Foo.M(obj); 

またはあなたはこのようにそれを呼び出すことができますが:

obj.M(); 

あなたが書いたコンパイラには違いありません。

これで、通常の一般的な方法と考えています。しかし、この観点から考えると、コンパイラーはジェネリック型パラメーターとして有効な任意の型でこのメソッドを呼び出せることを理解しているはずです。したがって、ジェネリック型パラメータとして有効な任意の型の拡張メソッドと考えることができる理由を理解できました。

+0

+1知っておくと便利な情報です。どのようにトリックが動作するのですか?私たちはこれが統語的な砂糖であると想定していますか?言い換えれば、コンパイラは単に 'obj.M()'の呼び出しを 'Foo.M(obj)'に変換しますか? –

+1

はい、構文糖だけです。言語仕様の7.6.5.2を参照してください。特に、そのセクションでは、「メソッド呼び出しは静的メソッド呼び出しとして処理されます」というステートメントが作成されます。 – jason

+0

@jason sytatic sugarについての95%の情報と、私たちが拡張しているものについての5%については、私たちがsystem.objectを拡張していないことを証明してください。 –

3

はい、タイプ制限を追加しない限り、System.Objectです。

+1

@RoyiNamir:ジェネリック**パラメータ**( 'Print ()')は、制約ではなく、 'どこT:SomeType'でも可能です。 –

+0

@GeorgeDuckett私はあなたがタイプを追加する必要がないことを意味しました。 T –

+0

オブジェクト上での拡張は、ジェネリック型のパラメータとして有効なすべての型に拡張するのと同じものではありません。これは 'object'の拡張ではありません。 – jason

関連する問題