1. ホーム
  2. c#

[解決済み] C#4 インターフェースで定義されたオプションパラメータは、なぜ実装クラスで強制されないのですか?

2022-03-23 08:14:29

質問

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に追加される予定です。