4
public class StoreController : Controller
{
    public string Index()
    {
        // implicitly specified instance does not work
        //return GetMemberName();

        // must specify this explicitly
        return this.GetMemberName();
    }
}

public static class Utilities
{
    public static string GetMemberName(this Controller caller,
        [CallerMemberName] string memberName = "")
    {
        return caller.GetType().FullName + "." + memberName;
    }
}

this拡張されるクラスのメソッド内から拡張メソッドを呼び出すときに、明示的に指定する必要があるのはなぜですか?

私のメンタルモデルでは、thisたとえばフィールドを初期化するときなど、通常は省略できます。

4

3 に答える 3

3

拡張メソッドは、技術的にはクラスにアタッチされたメソッドではありません。

yourClass.ExtensionMethod()と同じではありませんyourClass.ClassMethod()

基本的に、あなたがしていることはこれを行うための便利な方法を得ることです:

ExtensionMethod(YourClass yourClass) {
    //do something
    return yourClass;
}

それが拡張メソッドの私の理解です。これは、変更できないクラスに対してメソッドを呼び出すための便利な方法です。だから、それなしthis.ではそれを呼び出すことができない理由です。それはクラスメソッドではありません。

于 2012-10-17T07:02:58.603 に答える
2

拡張メソッドは、静的メソッドを呼び出すための単なる構文糖衣です。このコード行return this.GetMemberName();は、実際には次のような静的メソッドの呼び出しに変換されます。Utilities.GetMemberName(this);

ご覧のとおり、静的メソッドに送信する必要があり、それがキーワードthisが必要な理由です。this

于 2012-10-17T07:12:49.580 に答える
1

これが決定された設計委員会に出席しなければ、なぜそうなるのかはわかりません。

このテキストでは、特定のオブジェクトインスタンスに関連付けられた関数の意味でメソッドまたはインスタンスメソッドを使用し、数学的な意味で関数を使用します。関数はいくつかの引数を受け取り、結果を作成します(これは潜在的に無効です)

呼び出される実際の関数が実行時に決定されるため、より複雑な仮想メソッドを考慮しない場合、すべてのメソッド呼び出しは構文糖衣です。以下に定義されている2つのメソッドがある場合

internal static class Extensions {
  public static string FooEx(this MyClass self){
     return self.ToString();
  }
}

internal class MyClass {
  public string Bar(){
     var s1 = Foo();
     var s2 = this.FooEx();
  }

  private string Foo(){
      return ToString();
  }
}

次に、両方が関数呼び出しに変換されます。どちらの場合も、最初の(そして唯一の)引数は。で識別されるオブジェクトになりますthis。これについて疑問がある場合は、インスタンスメソッドの呼び出しに対して生成されたILを確認すると、コード内の宣言と比較して余分な引数があることに気付くでしょう。この引数はthis参照であり、常にインスタンスメソッドの最初の引数として渡されます。

したがって、インスタンスメソッドの場合でも、コンパイラは関数の最初の引数として渡すオブジェクトを決定する必要があります。これは、拡張メソッドを呼び出す場合とまったく同じです。これがないと、拡張メソッドの前でthis使用する必要がある本当の理由にはなりません。this

Marvinのコンパイラでは、Monoコンパイラの上にコンパイラを構築します。C#が拡張メソッドで行うのと同様のトリックを実行する必要があり、仕様に拡張メソッドの前this に使用を強制する本当の理由はなぜですか。thisスペックがそう言っていること。その決定の背後にある理由は、@ EricLippertのように、その要件を決定したときにおそらくそこにいる人の注意が必要なことです。

于 2012-10-18T09:06:38.680 に答える