私はこれを見ていましたブログ投稿そして次のような質問をしました:
- なぜこのキーワードが必要なのでしょうか
new
。これは、基本クラスのメソッドが非表示になっていることを指定するためだけですか。つまり、なぜ必要なのでしょうか。このキーワードを使用しないとoverride
、基本クラスのメソッドが非表示になるのではないですか。 - C# ではなぜデフォルトで非表示になり、上書きされないのでしょうか? 設計者はなぜこのように実装したのでしょうか?
ベストアンサー1
いい質問ですね。もう一度述べさせてください。
あるメソッドを別のメソッドで隠すことがなぜ合法なのでしょうか?
例を挙げてその質問に答えてみましょう。CLR v1 のインターフェースがあります。
interface IEnumerable
{
IEnumerator GetEnumerator();
}
素晴らしい。CLR v2ではジェネリックがあり、「v1にジェネリックがあったら、これをジェネリックインターフェースにしていたのに」と思うでしょう。しかし、そうしませんでした。今なら、それと互換性のあるものを作るべきです。はジェネリックを使用すると、IEnumerable を期待するコードとの下位互換性を失うことなく、ジェネリックの利点を享受できます。」
interface IEnumerable<T> : IEnumerable
{
IEnumerator<T> .... uh oh
のGetEnumeratorメソッドを何と呼びますかIEnumerable<T>
?覚えておいてください、欲しい非ジェネリック基本インターフェースでGetEnumeratorを非表示にするには、一度もない明示的に下位互換性のある状況でない限り、そのことを呼び出す必要があります。
それだけでメソッド隠蔽は正当化されます。メソッド隠蔽の正当化に関するさらなる考察については、このテーマに関する私の記事。
「new」なしで非表示にすると警告が表示されるのはなぜですか?
なぜなら、あなたが何かを隠していて、それを誤って行っている可能性があることに注意を喚起したいからです。覚えておいてください。派生クラスを編集したのではなく、他の誰かが基本クラスを編集したために、何かを誤って非表示にしてしまう可能性があります。
「new」なしで非表示にすると、エラーではなく警告になるのはなぜですか?
同じ理由です。新しいバージョンの基底クラスを選んだばかりなので、何かをうっかり隠してしまうかもしれません。これはよくあることです。FooCorp は基底クラス B を作成します。BarCorp は派生クラス D を作成し、そのメソッド Bar を使用します。これは、顧客がそのメソッドを好むためです。FooCorp はそれを見て、それはよい考えだ、その機能を基底クラスに組み込める、と言います。彼らはそれを実行し、Foo.DLL の新しいバージョンを出荷します。BarCorp が新しいバージョンを選んだとき、BarCorp のメソッドが基底クラスのメソッドを隠していることが伝えられると便利です。
私たちはその状況が警告そして、エラーなぜなら、それをエラーにすると、これは脆弱な基底クラスの問題の別の形であるC# は、基本クラスに変更を加えた場合に、派生クラスを使用するコードへの影響が最小限に抑えられるように慎重に設計されています。
なぜデフォルトを上書きせずに非表示にするのですか?
仮想オーバーライドは危険な仮想オーバーライドにより、派生クラスは基本クラスを使用するようにコンパイルされたコードの動作を変更できます。オーバーライドのような危険なことは、意識的にそして故意に偶然ではありません。