1. ホーム
  2. c#

[解決済み] 拡張クラスから拡張メソッドを呼び出すために 'this' キーワードが必要な理由

2023-06-22 13:35:59

質問

ASP.NET MVC ViewPageの拡張メソッドを作成しました。

public static class ViewExtensions
{
    public static string Method<T>(this ViewPage<T> page) where T : class
    {
        return "something";
    }
}

このメソッドを View から呼び出す場合 ( ViewPage から派生した)Viewからこのメソッドを呼び出すと、エラー "が発生します。 CS0103: 名前 'Method' は現在のコンテキストに存在しません。 を使用しない限り、エラーは発生しません。 this キーワードで呼び出さない限り、存在しません。

<%: Method() %> <!-- gives error CS0103 -->
<%: this.Method() %> <!-- works -->

なぜ this キーワードが必要なのでしょうか?それとも、なくても動作しますが、私が何かを見逃しているのでしょうか?

(私はこの質問の重複があるはずだと思うが、私はそれを見つけることができなかった)

更新 :

として ベン・ロビンソンのコメント のように、拡張メソッドを呼び出す構文はコンパイラの砂糖に過ぎません。では、なぜコンパイラはthisキーワードを必要とせずに、現在の型の基底型の拡張メソッドを自動的にチェックできないのでしょうか?

どのように解決するのですか?

いくつかのポイントがあります。

まず、提案されている機能(拡張メソッド呼び出し時の暗黙の "this.")は 不要 . 拡張メソッドは、LINQ クエリ内包が私たちの望む方法で動作するために必要でした。レシーバーは常にクエリで指定されるため、LINQ を動作させるために暗黙の this をサポートする必要はありません。

第二に、機能が動作する に対して に対して機能します。すなわち、拡張メソッドは 自分では拡張できない型を拡張することができる つまり、拡張メソッドは、インターフェイスであり実装を知らない、または実装を知っているがソースコードを持っていないという理由で、自分では拡張できない型を拡張することができるということです。

もし、ある型の拡張メソッドを使用するシナリオがある場合 その型の中で である場合、あなたは する はソースコードにアクセスすることができます。 では、なぜそもそも拡張メソッドを使用しているのですか? を書けばいいのです。 インスタンスメソッド を自分で書けば、拡張メソッドを使う必要はありません。そうすれば、拡張メソッドを使用する必要はまったくありません!実装は、拡張メソッドではできない、オブジェクトのプライベートな状態へのアクセスを利用することができます。

アクセス可能な型の中から拡張メソッドを使いやすくすることは、インスタンスメソッドよりも拡張メソッドを使うことを推奨しています。拡張メソッドは素晴らしいものですが、通常はインスタンスメソッドがあればそれを使用した方がよいでしょう。

この2点を踏まえると、もはや言語設計者には、なぜその機能が ではない が存在しない理由を説明する責任は、もはや言語設計者にはありません。今度はあなたが、なぜその機能が べきである . 機能には莫大なコストがかかるものです。この機能は必要なく、拡張メソッドの設計目標に反しています。なぜ私たちはこの機能を実装するコストを負わなければならないのでしょうか? この機能によってどのような説得力のある重要なシナリオが可能になるのか説明してください、そうすれば将来的に実装を検討します。この機能を正当化するような、説得力のある重要なシナリオは見当たりませんが、もしかしたら私が見逃しているものがあるのかもしれません。