3

言語仕様に従ってhttp://msdn.microsoft.com/en-us/library/bb383977.aspx

拡張メソッドを使用してクラスまたはインターフェイスを拡張できますが、オーバーライドすることはできません。インターフェイスまたはクラス メソッドと同じ名前とシグネチャを持つ拡張メソッドは呼び出されません。コンパイル時には、拡張メソッドは型自体で定義されたインスタンス メソッドよりも優先度が常に低くなります。

私が理解できないのは、なぜこの制限があるのですか? オーバーライド拡張機能を許可すると、どのようなプログラミング上の問題が発生しますか?

簡単なケーススタディ

基本クラスObjectにはメソッド ToString() があり、デフォルトではオブジェクト型名を文​​字列に返します。すべての意図と目的のために、オーバーライドできるように設計されていると主張できます。

デフォルトでは、バイトを文字列に変換することが意味があるかどうかがわからないため、 aStreamはオーバーライドを提供しません。ToString

ただし、ソリューションのプログラマーとして、文字列に変換された場合、すべてのストリームが意味を持つことを知っています。ただし、ストリーム クラスから派生させたくない、または派生させることはできません。ToStringしたがって、ストリームを文字列に変換するメソッドを拡張したいと思います。そのようです:

public static String ToString(this Stream stream)
{
    var memory = new MemoryStream(); //closable
    var reader = new StreamReader(memory);
    stream.Position = 0;
    stream.CopyTo(memory);
    memory.Position = 0;
    return reader.ReadToEnd();
}

ただし、仕様によると、これは実行時に呼び出されることはありません。しかし、この場合、なぜ制限を厳しくする必要があるのでしょうか。Streamから派生したようObjectに、特に拡張メソッドStreamはデフォルトで基本型メソッドをオーバーライドする必要があるという意味ではありませんか?

さらに、単に名前を付けるだけでAsStringは役に立たない場合もあります。つまりToString、アイテムを表すフォールバックとして使用する WPF です。

4

1 に答える 1

4

拡張メソッドは、拡張オブジェクトの継承階層の外にあります。

言語 (および IDE) は、この完全に別のクラスを拡張型の一部のように見せるだけです。

オーバーライドを可能にするには、継承モデルと拡張メカニズム全体を変更する必要があります。これは非常に大きな変更であり、おそらく破壊的なものです。

要するに、これは実装コストがその有用性を上回る機能です。

于 2013-03-06T12:37:20.747 に答える