2

重複の可能性:
拡張クラス内から拡張メソッドを呼び出すために「this」キーワードが必要なのはなぜですか

特定の名前空間の下のアセンブリで宣言された拡張メソッドがあります。これは非常に一般的なヘルパーです。

using System;

namespace Common {
    public static class GenericServiceProvider {
        public static T GetService<T>(this IServiceProvider serviceProvider) {
             return (T)serviceProvider.GetService(typeof(T));
        }
    }
}

別のアセンブリと名前空間で、IServiceProviderを実装するクラスからこの拡張メソッドにアクセスしようとしています。

using System;
using Common;

namespace OtherNamespace {
    class Bar: IServiceProvider {
        void Foo() {
            GetService<IMyService>(); // doesn't compile
            this.GetService<IMyService>(); // compiles
        }
    }
}

ご覧のとおり、ジェネリック拡張メソッドを直接呼び出すことはできません。IntelliSenseにも表示されません。ただし、呼び出しの前に「this」を追加すると、正常に機能します。

これは、.NET4を使用するVisualStudio2010にあります。

これは正常ですか、それとも私は何か間違ったことをしていますか?ありがとう。

4

3 に答える 3

4

これは正常ですか、それとも私は何か間違ったことをしていますか?ありがとう。

これは正常です。拡張メソッドは何かを拡張する必要があります。コンパイラは、「式」(。 "の左側)として何かがない限り、拡張メソッドを検索しません。これは、C#言語仕様7.6.5.2で定義されています。

7.6.5.2 Extension method invocations

In a method invocation (§7.5.5.1) of one of the forms
expr . identifier ( )
expr . identifier ( args )
expr . identifier < typeargs > ( )
expr . identifier < typeargs > ( args )

基本的に、 exprには常に何かが必要です。この場合、は機能し、コンパイラはこれを次のように書き換えることができます。this

C . identifier ( expr ) 
于 2012-06-13T18:01:58.430 に答える
1

これは、そのタイプのオブジェクトでのみ拡張メソッドを使用でき、クラスはIServiceProviderを継承するためthis.、この場合は使用する必要があるためです。私はこれをあなたの答えにするあなたの質問を理解することを願っていますが、GetService(); いずれの場合も、拡張メソッドの構文が正しくないため、不可能です。

于 2012-06-13T17:56:59.390 に答える
0

拡張メソッドは、objects/Classのインスタンスで使用するためのものです。この場合、クラスの一意のインスタンスのように機能する静的クラスがあります。

したがって、拡張メソッドを作成すると、オブジェクトのインスタンスがそれを使用できるようになります。

于 2012-06-13T18:00:20.147 に答える