c# - 設計 - 抽象クラス インターフェース




C#4のオプションパラメータは、実装クラスで強制されないインターフェイスで定義されるのはなぜですか? (3)

私は、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フレームワークを使用します)、実際にはありません呼び出し側が常にそれを提供しなければならないため、デフォルト値を持つポイントが必要です。


オプションのパラメータは、私が理解しているものからマクロ置換のようなものです。 メソッドの観点からは実際にはオプションではありません。 その成果物は、インターフェイスにキャストすると異なる結果が得られる場所で見られる動作です。


オプションのパラメータは属性でタグ付けされています。 この属性は、コールサイトでそのパラメータのデフォルト値を挿入するようにコンパイラに指示します。

呼び出しobj2.TestMethod(); obj2.TestMethod(false);置き換えられobj2.TestMethod(false); C#コードがJIT時ではなくILにコンパイルされたとき。

だから、常にオプションのパラメータでデフォルト値を提供するのは呼び出し元です。 バイナリのバージョン管理にも影響します。デフォルト値を変更しても、呼び出し元のコードを再コンパイルしないと、古いデフォルト値が引き続き使用されます。

一方、この切断は、コンクリートクラスとインタフェースを常に同じ意味で使うことができないことを意味します。

インタフェースメソッドが明示的実装されていれば、すでにそれを行うことはできません。


更新: この質問は2011年5月12日に私のブログの主題でした。すばらしい質問をありがとう!

あなたが記述しているようなインターフェースを持っていて、それを実装する100のクラスがあるとします。 次に、インタフェースのメソッドの1つのパラメータの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の新しいバージョンを出荷してもらえますか?

それは飛ぶつもりはない。 もし2人がBの著者を呼び、そのうちの1人がデフォルトを真実にしたいとし、そのうちの1人が偽であることを望むとしたらどうでしょうか? Bの作者が単に遊ぶことを拒否すればどうなるでしょうか?

おそらくその場合、彼らは言うべきことが必要になるでしょう:

class D : B, MyInterface 
{
    public new void TestMethod(bool b = false)
    {
        base.TestMethod(b);
    }
}

提案された機能は、それに対応する代表的なパワーの増加がないプログラマーに多くの不便さを加えるようである。 ユーザーのコスト増加を正当化する、この機能の魅力的なメリットは何ですか?





optional-parameters