2011-11-14 12 views
4

は、以下のコンソールアプリケーションを考えてみます。C#4.0デフォルトパラメータ

class Program 
{ 
    static void Main() 
    { 
     MyInterface test = new MyClass(); 
     test.MyMethod(); 

     Console.ReadKey(); 
    } 
} 

interface MyInterface 
{ 
    void MyMethod(string myString = "I am the default value on the interface"); 
} 

class MyClass : MyInterface 
{ 
    public void MyMethod(string myString = "I am the default value set on the implementing class") 
    { 
     Console.WriteLine(myString); 
    } 
} 

このプログラムからの出力である:

I am the default value on the interface 

(1)なぜなどのパラメータを指定する方法がありません値を指定せずにインタフェース上のオプション。私はデフォルト値を実装の詳細と考えています。このコードを事前オプションのパラメータスタイルで記述した場合、インタフェースに2つのオーバーロードが作成され、実装クラスにデフォルト値が指定されます。私。我々は持っているでしょう:

我々が期待通りに出力
interface MyInterface 
{ 
    void MyMethod(); 

    void MyMethod(string myString); 
} 

class MyClass : MyInterface 
{ 
    public void MyMethod() 
    { 
     MyMethod("I am the default value set on the implementing class"); 
    } 

    public void MyMethod(string myString) 
    { 
     Console.WriteLine(myString); 
    } 
} 

I am the default value set on the implementing class 

(2)なぜ実装するクラスでは、デフォルト値を上書きすることはできません!

答えて

4

.Netのデフォルト値は、実際にはコンパイラベースの構文的な砂糖です。コールサイトでは、コンパイラがデフォルト値を追加します。コンパイル時にオブジェクトの実行時の型を知ることができないため、インタフェースに定義された値を挿入する必要があります。

したがって、オーバーライドするものがないため、実装では「オーバーライド」できません。

Eric Lippertは、オプションの議論の対象について、非常に興味深い一連のブログ記事を書いていました。最初はhereです。

更新
あなたのコメントからは、何を示唆していると、CLRは「について知っている」しなければならない(実行時の型が宣言されている)「仮想」パラメータのいくつかの形式のいずれかです。私はこの実装がコスト(設計、文書化、実装、テストなど)が与えられた利点と比較して高すぎるために除外されたと推測しています(これは単なる推測ですが)。

void M(bool y = false) { ... whatever ... } 

のように、コンパイラによって再書き込まれます:

void M() { M(false); } 
void M(bool y) { ... whatever ... } 

しかし、このルートが過負荷に一度、複数のオプションの引数の潜在的に許容できないレベルにつながる下る はまた、デフォルトの委任方法のオプション、すなわちあります名前のついた議論が意識される。

+0

豊かな乾杯、私は問題を参照してください。インターフェイスに値を指定するのではなく、「オプションの」キーワードを追加した方が意味をなさないでしょうか?インターフェイスにデフォルト値を設定する必要はありません。 – magritte

3

1)あなたの考えに欠陥があります。デフォルト値は実装の詳細です。インタフェースには実装の詳細はありません。そのロジックによって、デフォルト値を指定することは実際にはインターフェースには属しません。

オーバーロードされたメソッドを使用してインターフェイスを記述するだけです。定義がより明確になるだけでなく、他の言語とのインタフェース時に互換性が向上し、オプションのパラメータに伴うバージョン管理の問題は発生しません。

2)インタフェースが運用契約を定義しているため。インターフェイスは、デフォルトが何かでなければならないと言います。したがって、クラスはそれをそのように実装する必要があります。

+0

(1)確かに私は同意します。ただし、省略した場合、パラメータがオプションであることがわからないため、コンパイラの警告が表示されます。これは私の質問につながります(1)なぜ値を指定せずにオプションとして指定できないのですか? – magritte

+0

@Tony Leeper - Twitter経由でEric Lippertからコーナーケースも入手できました:http://blogs.msdn.com/b/ericlippert/archive/2011/05/09/optional-argument-corner-cases-part -one.aspx –

関連する問題