2010-12-14 14 views
7

C#のStructジェネリックコンストラクタ

struct Foo<T1> 
{ 
    public T1 Item1 { get; private set; } 

    public Foo(T1 item1) 
    { 
     Item1 = item1; 
    } 
} 

私はこのエラーが発生した:コンストラクタが呼び出された後

Backing field for automatically implemented property 'Foo.Item1' must be fully assigned before control is returned to the caller. Consider calling the default constructor from a constructor initializer.

私の質問は、なぜプロパティItem1は完全に割り当てられていませんか?

編集:setからprivate setに変更されました。この問題は変更可能性とは関係がないためです。

+10

変更可能な構造体を作成しないでください。 –

+0

なぜ彼はいけないのですか?実際には、実際には多くの場合単純なものになり、ループ集約的なケースではパフォーマンスがかなり向上する可能性があります。変更可能な構造体で何が問題になっていますか? (それは彼の質問にも答えません) – Mehrdad

+0

@Lambert http://stackoverflow.com/questions/441309/why-are-mutable-structs-evil –

答えて

15

はここでthis()を追加します。

public Foo(T1 item1) : this() 
{ 
    Item1 = item1; 
} 

あなたがプロパティに代入しているので、それはだ、とコンパイラはプロパティだけ変数に値を代入することを推測することはできません。インスタンスが初期化される前に他の処理を行うことができますが、構造体にガベージ・データがある可能性があるため、これは許可されません。そのため、まずデフォルトのコンストラクタで初期化してから、必要な処理を行う必要があります。

+0

@Lambert:問題は、コンパイラが明白なのはなぜですか?コンパイラは、他のケースでは、フロー解析の優れた仕事をしています。 – Vlad

+0

私はコンパイラを作っていないので、わかりません。 :)しかし、それはプロパティが自動生成されていない他の状況、およびガベージデータを使用しようとする場所を防ぎます。 また、これはCLRの問題ではなく、コンパイラの問題ではないと思われます.JITは、インスタンスが初期化される前にプロパティにアクセスしようとすると、コンパイラがすぐに利用できる情報を持っていないためそれ。 – Mehrdad

+0

また、独自のデフォルトコンストラクタを明示的に実装することで、これを解決することもできます。 –