言語仕様に従って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 です。