[解決済み] C#4 インターフェースで定義されたオプションパラメータは、なぜ実装クラスで強制されないのですか?
質問
C# 4のオプショナルパラメータで、インターフェースにオプショナルパラメータを指定すると、次のようなことが起こることに気づきました。 しない は、実装クラスでそのパラメータをオプションにする必要があります。
public interface MyInterface
{
void TestMethod(bool flag = false);
}
public class MyClass : MyInterface
{
public void TestMethod(bool flag)
{
Console.WriteLine(flag);
}
}
であり、したがって
var obj = new MyClass();
obj.TestMethod(); // compiler error
var obj2 = new MyClass() as MyInterface;
obj2.TestMethod(); // prints false
オプショナルパラメーターがなぜこのような仕組みになっているのか、ご存知の方はいらっしゃいますか?
一方で、インターフェースで指定されたデフォルト値を上書きできるのは便利だと思いますが、正直なところ、インターフェースでデフォルト値を指定できるようにする必要があるのかどうか、それは実装の決定事項であるべきだと思います。
一方、この切断は、具象クラスとインターフェイスを常に使い分けられるとは限らないことを意味します。もちろん、デフォルト値が実装で指定されていれば問題ないのですが、インターフェイスとして具象クラスを公開している場合(例えば具象クラスをインジェクトするためにIOCフレームワークを使用している)、呼び出し元が常にデフォルト値を提供しなければならないので、実際にはデフォルト値を持つ意味はありません。
どうすればいい?
UPDATE この質問は、2011年5月12日のブログで取り上げました。素晴らしい質問をありがとうございました。
あなたが説明したようなインターフェイスがあり、それを実装したクラスが100個あったとします。そして、そのインターフェースのメソッドのパラメータの1つをオプションにすることにしたとします。あなたは、コンパイラが開発者にそのインターフェイスメソッドのすべての実装を見つけさせ、そのパラメータもオプションにすることが正しいことだと言いたいのでしょうか?
仮にそうしたとします。さて、開発者がその実装のソースコードを持っていなかったとします。
// in metadata:
public class B
{
public void TestMethod(bool b) {}
}
// in source code
interface MyInterface
{
void TestMethod(bool b = false);
}
class D : B, MyInterface {}
// Legal because D's base class has a public method
// that implements the interface method
Dの作者はこれをどのように実現すればいいのでしょうか?あなたの世界では、彼らはBの作者を電話で呼び出して、メソッドにオプションのパラメータを持たせるBの新しいバージョンを送ってくれるよう頼む必要があるのでしょうか?
そんなことは通用しない。もし に がBの作者を呼び出し、一人はデフォルトが真であることを望み、一人は偽であることを望んでいるのでしょうか?Bの作者が単に拒否したらどうでしょうか?
おそらくその場合は、こう言うことを要求されるのでしょう。
class D : B, MyInterface
{
public new void TestMethod(bool b = false)
{
base.TestMethod(b);
}
}
提案された機能は、プログラマーに多くの不便を強いるようで、それに見合った代表力の向上がありません。この機能には、ユーザーへのコスト増を正当化するような、やむを得ないメリットがあるのでしょうか?
UPDATE: 以下のコメントで、supercatさんが、この質問に書かれているようなシナリオを可能にする、純粋に言語のパワーを高める機能を提案してくれています。参考までに、その機能(インターフェースにおけるメソッドのデフォルト実装)は、C# 8に追加される予定です。
関連
-
[解決済み】スクリプトクラスが見つからないので、スクリプトコンポーネントを追加できない?
-
[解決済み】値が期待した範囲に収まらない
-
[解決済み] EntityTypeにキーが定義されていないエラー
-
[解決済み】Unity 「関連するスクリプトを読み込むことができません」「Win32Exception: システムは指定されたファイルを見つけることができません"
-
[解決済み】ファイルへの読み書きの際に共有違反のIOExceptionが発生する C#
-
[解決済み] 2つのリストを結合する
-
[解決済み】Microsoft.Extensions.LoggingからILoggerを解決することができない
-
[解決済み】スレッド終了またはアプリケーションの要求により、I/O操作が中断されました。
-
[解決済み】なぜインターフェース変数は、デフォルトでstaticとfinalなのですか?
-
[解決済み】同じメソッドを持つクラスで2つのインターフェースを実装する。どのインターフェイスのメソッドがオーバーライドされるか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】文字列が有効な DateTime " format dd/MM/yyyy " として認識されなかった。
-
[解決済み】ASP.NET Core Dependency Injectionのエラーです。アクティブ化しようとしているときに、タイプのサービスを解決できません。
-
[解決済み】C#はJavaのcharAt()と同等?)
-
[解決済み】「namespace x already contains a definition for x」エラーの修正方法は?VS2010にコンバートした後に発生しました。
-
[解決済み】リソースの読み込みに失敗した:ステータス500(内部サーバーエラー)のサーバーの応答)
-
[解決済み】EF 5 Enable-Migrations : アセンブリにコンテキストタイプが見つかりませんでした
-
[解決済み】Linq 構文 - 複数列の選択
-
[解決済み】ユーザー設定値を別のユーザー設定値で設定する
-
[解決済み】名前 'ViewBag' が現在のコンテキストに存在しない - Visual Studio 2015
-
[解決済み】スレッド終了またはアプリケーションの要求により、I/O操作が中断されました。