1. ホーム
  2. c#

[解決済み] なぜnewキーワードが必要なのか、なぜデフォルトの動作はhideでありoverrideではないのか?

2023-06-25 02:44:38

質問

私はこれを見ていました ブログ記事 を拝見し、以下のような疑問を持ちました。

  • なぜ new キーワードが必要なのは、ベースクラスのメソッドが隠されていることを指定するためだけなのでしょうか。つまり、なぜそれが必要なのでしょうか?もし override キーワードを使用しない場合、ベース・クラス・メソッドを隠していないのでしょうか?
  • なぜ C# のデフォルトは非表示でオーバーライドではないのですか?設計者はなぜこのように実装したのでしょうか。

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

良い質問ですね。もう一度説明しましょう。

<ブロッククオート

なぜ、あるメソッドを別のメソッドで隠すことがまったく合法なのですか?

その質問に例で答えましょう。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は顧客がそのメソッドを好むので、Barメソッドを持つ派生クラスDを作成します。FooCorpはそれを見て、これはいいアイデアだ、その機能を基底クラスに追加しよう、と言う。そして、Foo.DLL の新しいバージョンを出荷します。BarCorp がその新しいバージョンを手に取ったとき、そのメソッドがベースクラスのメソッドを隠すようになったと言われたら、それは素晴らしいことでしょう。

私たちはそのような状況を 警告 ではなく エラー というのは、エラーにするということは これは脆い基底クラス問題の別の形態です。 . C# は、誰かが基底クラスを変更したときに、派生クラスを使用するコードへの影響を最小限に抑えるように慎重に設計されています。

なぜ隠蔽し、オーバーライドしないことがデフォルトなのですか?

なぜなら仮想オーバーライドは 危険 . 仮想オーバーライドは、派生クラスがベースクラスを使用するようにコンパイルされたコードの振る舞いを変更することを可能にします。 オーバーライドを行うような危険なことは、あなたが行うべきことです 意識的に であり 意図的に であって、偶然ではありません。