6

実装者からインターフェイスで機能する拡張メソッドを呼び出すには、thisキーワードを使用する必要があるようです。これは奇妙に思えます。

誰かが理由を知っていますか?

インターフェイスの共有実装を取得する簡単な方法はありますか?

多重継承/ミックスインの撤回に苦しんでいるので、これは私を苛立たせます。

おもちゃの例:

public interface ITest
{
    List<string> TestList { get; }
}

public static class TestExtensions
{
    private const string Old = "Old";
    private const string New = "New";

    public static void ManipulateTestList(this ITest test)
    {
        for (int i = 0; i < test.TestList.Count; i++)
        {
            test.TestList[i] = test.TestList[i].Replace(Old, New);
        }
    }
}

public class Tester : ITest
{
    private List<string> testList = new List<string>();
    public List<string> TestList
    {
        get { return testList; }
    }

    public Tester()
    {
        testList.Add("OldOne");
        testList.Add("OldTwo");

        // Doesn't work
        // ManipulateTestList();

        // Works
        this.ManipulateTestList();
    } 
}
4

3 に答える 3

4

私はこの正確な質問を言語チームに直接尋ねました。手元にある電子メールはありませんが、基本的に(Mads、IIRCからの)答えは次のとおりです。

  • 検索スペース/複雑さを減らすために-つまり、最初に式がない限り、利用可能なすべての拡張メソッドを考慮する(そしてそれらを整理する)必要はありません。
  • 拡張メソッドが通常のメソッドを「引き継ぐ」(つまり、より適切に一致する)可能性を減らすため

個人的には、それが一貫して機能することを望んでいました-最初のものは大きな問題ではないようです(しかし、私はコンパイラを作成しません)、そしてどちらもthis.*通常はオプションのものであるという事実に近づきません(それはそのような影響を与える可能性がありますローカルコードスタイルのガイドラインとして、つまり「使用する必要がありますthis.」)。

于 2010-09-15T06:57:12.517 に答える
3

言語仕様の関連セクションには、次のように書かれています。

7.6.5.2拡張メソッドの呼び出し

フォームの1つのメソッド呼び出し(§7.5.5.1)

  • expr . 識別子 ( )
  • expr . 識別子 ( 引数 )
  • expr . 識別子 < typeargs > ( )
  • expr . 識別子 < typeargsargs > ( _ )

呼び出しの通常の処理で適用可能なメソッドが見つからない場合、拡張メソッド呼び出しとして構成を処理しようとします。exprまたはいずれかのargs がコンパイル時タイプの場合dynamic、拡張メソッドは適用されません。

これは、拡張メソッドは式(expr)でのみ呼び出すことができることを明確に示しています。もちろん、この式は「<code> this」にすることができますが、存在している必要があります。

于 2010-09-15T06:32:54.573 に答える
1

拡張メソッドは、呼び出しを別の静的クラスの静的メソッドにリダイレクトするオブジェクトで機能するコンパイラのトリックです。'これ。コンパイラが静的メソッドを渡すオブジェクトです。動作しない例は、メソッドがクラスにスコープされていないことをコンパイラが通知し、インスタンスメソッドがスコープされていることです。

于 2010-09-15T06:30:58.163 に答える