C# オーバーライドされたメソッドのオプションパラメータ
質問
.NET Frameworkで、メソッドをオーバーライドするときに、オプションのパラメータに問題があるようです。下記のコードの出力は "bbb" "aaa" . しかし、私が期待している出力は "bbb" "bbb" .これに対する解決策はありますか。私はそれがメソッドのオーバーロードで解決することができることを知っていますが、この理由を疑問に思っています。また、コードはMonoでうまく動作します。
class Program
{
class AAA
{
public virtual void MyMethod(string s = "aaa")
{
Console.WriteLine(s);
}
public virtual void MyMethod2()
{
MyMethod();
}
}
class BBB : AAA
{
public override void MyMethod(string s = "bbb")
{
base.MyMethod(s);
}
public override void MyMethod2()
{
MyMethod();
}
}
static void Main(string[] args)
{
BBB asd = new BBB();
asd.MyMethod();
asd.MyMethod2();
}
}
どのように解決するのですか?
ここで注意すべき点は、オーバーライドされたバージョンが毎回呼び出されることです。オーバーライドを変更します。
public override void MyMethod(string s = "bbb")
{
Console.Write("derived: ");
base.MyMethod(s);
}
と出力されます。
derived: bbb
derived: aaa
クラス内のメソッドは、次のうち1つまたは2つを行うことができます。
- 他のコードが呼び出すためのインターフェイスを定義する。
- 呼び出されたときに実行するための実装を定義します。
抽象メソッドは前者のみを行うので、両方を行うことはできないかもしれません。
内では
BBB
呼び出し
MyMethod()
はメソッドを呼び出します。
定義された
で
AAA
.
にオーバーライドがあるため
BBB
に実装されているので、そのメソッドを呼び出すと
BBB
が呼び出されることになります。
では、定義された
AAA
の定義は呼び出し側のコードに2つのことを知らせます (まあ、ここでは重要でないいくつかの他のこともですが)。
-
シグネチャ
void MyMethod(string)
. -
(サポートしている言語では)単一パラメータのデフォルト値は
"aaa"
であり、したがって、以下の形式のコードをコンパイルするときはMyMethod()
にマッチするメソッドがない場合はMyMethod()
にマッチするメソッドが見つからない場合は、 `MyMethod("aaa")' の呼び出しに置き換えることができます。
での呼び出しがそうなんですね。
BBB
の呼び出しがそうさせるのです。コンパイラは
MyMethod()
への呼び出しを見ますが、メソッド
MyMethod()
は見つかりませんでしたが、メソッドが見つかりました。
MyMethod(string)
. また、このメソッドが定義されている場所にはデフォルト値として "aaa" があることもわかりました。
MyMethod("aaa")
.
内部から
BBB
,
AAA
は、その場所とされる
AAA
のメソッドが定義される場所とみなされます。
BBB
でオーバーライドされたとしても
ができます。
を上書きすることができます。
ランタイムに
MyMethod(string)
は引数 "aaa" で呼び出されます。オーバーライドされたフォームがあるため、そのフォームが呼び出されますが、その値は実行時の実装とは関係なく、コンパイル時の定義であるため、"bbb" で呼び出されることはありません。
追加する
this.
を追加すると、どの定義が調べられるかが変わるので、呼び出しで使用される引数も変わってきます。
編集:なぜこれがより直感的に思えるのか。
個人的には、何が直感的かについて話しているので、それは個人的なものでしかありませんが、次の理由から、私はこの方が直感的であると思います。
私がコーディングしていた場合
BBB
を呼び出してもオーバーライドしても
MyMethod(string)
を実行することだと考えています。
AAA
stuff" - それは
BBB
のテイクオン。
AAA
をすることです。
AAA
をやっているのと同じです。したがって、呼び出すにせよオーバーライドするにせよ、私はそれが
AAA
を定義したのは
MyMethod(string)
.
を使用するコードを呼び出す場合
BBB
を使用するコードを呼び出しているとしたら、私は次のように考えるでしょう。
BBB
のもの"です。で元々定義されていたものがどれなのか、あまり意識していないかもしれません。
AAA
で定義されたものをあまり意識しないかもしれませんし、これは単なる実装の詳細だと思うかもしれません(もし、私がまた
AAA
インターフェースも使っていなければ)。
コンパイラの動作は私の直感と一致します。そのため、最初に質問を読んだとき、Monoにバグがあるように思えたのです。考慮した結果、私は、どちらかが他よりも指定された動作をよりよく満たすということは見当たりません。
そのことについては、個人的なレベルにとどまっていますが、私は抽象的、仮想的、またはオーバーライドされたメソッドでオプションのパラメーターを決して使用せず、そうする他の誰かのものをオーバーライドする場合、私は彼らのものと一致させます。
関連
-
[解決済み】MetadataException: 指定されたメタデータ・リソースをロードできない
-
[解決済み】「...は'型'であり、与えられたコンテキストでは有効ではありません」を解決するにはどうすればよいですか?(C#)
-
[解決済み】2つ(またはそれ以上)のリストを1つに統合する(C# .NETで
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] EqualsメソッドがオーバーライドされたときにGetHashCodeをオーバーライドすることが重要な理由は何ですか?
-
[解決済み] Javaオプションパラメータ
-
[解決済み] クラス内の項目の並び順。フィールド、プロパティ、コンストラクター、メソッド
-
[解決済み] C#でオプションのパラメータを使用するにはどうすればよいですか?
-
[解決済み] Swiftのプロトコルでオプションのメソッドを定義するには?
-
[解決済み] C#4 インターフェースで定義されたオプションパラメータは、なぜ実装クラスで強制されないのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] エンティティタイプ ApplicationUser は、現在のコンテキストのモデルの一部ではありません。
-
[解決済み】コンパイルエラー「未割り当てのローカル変数を使用しています」が発生したのはなぜですか?
-
[解決済み] エンティティタイプ <type> は、現在のコンテキストのモデルの一部ではありません。
-
[解決済み】Sequence contains no matching element(シーケンスにマッチする要素がない
-
[解決済み】値が期待した範囲に収まらない
-
[解決済み] EntityTypeにキーが定義されていないエラー
-
[解決済み】Visual Studio: 操作を完了できませんでした。パラメータが正しくありません
-
[解決済み】名前 'ViewBag' が現在のコンテキストに存在しない - Visual Studio 2015
-
[解決済み】データが存在しないのに読み込もうとする試みが無効である
-
[解決済み] C#や.NETで最悪のガチャは何ですか?[クローズド]