2011-09-23 46 views
10

でアクセスしようとすると、structに関する1つの観察がある。私は、構造体のプロパティを宣言し、私はその後、構造体を初期化していない場合、それは私に、以下のエラーを与えるとき -structが初期化されていないときにコンパイラがエラーを返すが、変数にアクセスしようとしたときに変数

PSeduoコード -

struct EmpStruct 
{ 
    private int firstNumber; 
    public int FirstNumber 
    { 
     get { return firstNumber; } 
     set { firstNumber = value; } 
    } 

    public int SecondNumber; 

} 

Program.cs-「未割り当てのローカル変数empStructの使用を」

EmpStruct empStruct; 
empStruct.FirstNumber = 5; 

しかし、私は公共の変数を宣言すると上記のコードが動作します。

EmpStruct empStruct; 
empStruct.SecondNumber; 

私は変数にアクセスしようとすると、コンパイラがエラーを与えていない、なぜ私の質問です。(クラスの場合、それはエラーになります)。

+3

すべての回答を下降させている人は、間違っている理由についてのコメントを残してください。私はPunitのポストに基づいて意味をなさないので、彼らをアップアップしています... –

+1

@bemused:彼らはすべて間違っています。そして理由を説明するコメントを残しました。 – jason

答えて

11

このスレッドには多大な混乱があります。

原則はstructのインスタンスのすべてのフィールドが確実に割り当てられるまでインスタンス上のプロパティまたはメソッドを呼び出すことができません。

これは、コードの最初のブロックがコンパイルされない理由です。すべてのフィールドを確実に割り当てることなく、プロパティにアクセスしています。

コードの2番目のブロックは、すべてのフィールドが確実に割り当てられていないフィールドにアクセスしても問題ないので、コンパイルされます。間違いなくstructを割り当てる

一つの方法は、これは間違いなくすべてのフィールドを割り当てますEmpStructのデフォルトのパラメータなしのコンストラクタを呼び出し

EmpStruct empStruct = new EmpStruct(); 

と言うことです。

仕様の該当するセクションは、確定割り当てに関する5.3項です。構築された構造体のすべてのフィールドが明確に割り当てられているまでの例から§11.3.8

に(プロパティXYの設定アクセサを含む)なしインスタンスメンバ関数が呼び出されることができません。

それは、より参考になる(エリックリペット、エヘン!)コンパイラのエラーメッセージが確実に割り当てられていないローカル変数empStruct

利用のラインに沿っていた場合。

次に、仕様内で何を検索するか、またはGoogleで検索するのが明確になります。

ここで、可変構造体を定義したことに注意してください。これは危険で悪です。あなたはそれをしてはいけません。代わりに、firstNumbersecondNumberを確実に割り当て、公式セッターをEmpStruct.FirstNumberから削除するパブリックコンストラクタを追加します。

+0

+1、Good catch regargdingプロパティのアクセサです! – sll

+0

スレッドをクリアしてくれてありがとう。私は誰もが混乱させた質問の言葉遣いだったと思う。 –

+0

ありがとう – Punit

3

に関してフィールド C#言語仕様は言う:それは静的フィールドまたは インスタンスフィールドであるかどうか

10.5.4フィールドの初期化

フィールドの初期値を、ありますフィールドの型のデフォルト値(5.2)。 初期化が発生している。このデフォルトの前にフィールドの値を観察する ことはできません、そしてフィールドがあるため、

しかしこれ

11.3.4デフォルト値決して」初期化されていません構造体はヌル値ではない値型です。構造体のデフォルト値は、すべての値の 型をデフォルト値に設定し、すべての参照型フィールドを nullに設定した値です。構造体のデフォルト値は、struct(§4.1.2)のデフォルトコンストラクタによって返される値 に対応します。

PS:あなたがそれらを使用する前にローカル変数を初期化する必要があるため、クラスの場合には、それはデフォルトで参照型の値は、あなたの最初の例では

+0

これは関連しません。エラーの理由は説明しません。 – jason

+0

@Jason:フィールドやクラスのケースでは関連しますが、プロパティに関連するエラーはありません。依然として仕様書 – sll

+0

で答えが見つかりません申し訳ありませんが、それはまったく関係ありません。エラーの理由は、EmpStructへの明確な割り当ての欠如に関係しています。あなたが引用した仕様のセクションは、明確な割り当てへの参照をしません。 §5.3および§11.3.8を参照のこと。 – jason

1

nullであるため、コードが動作しないエラーを与えます。 「デフォルト」の値はありません。最初に初期化する必要があります。すべてのローカル変数は、使用する前に常に初期化する必要があります。例えば:クラスの

EmpStruct empStruct = new EmpStruct(); 
empStruct.FirstNumber = 5; 

フィールドは、この同じ制限はありません。明示的に初期化しないと、デフォルト値で自動的に初期化されます。実際には、ランタイムはクラスのフィールドで自動的に "new EmpStruct()"を呼び出します。それで、あなたの2番目の例がうまくいくのです。

+0

これは意味をなさない。なぜコンパイラは2番目のブロックで 'new EmpStruct'を呼び出しますが、最初のブロックでは呼び出さないのでしょうか?この答えは、2つのコードブロックに違いがある理由を説明していません。 – jason

+0

ああ...私は元の質問を理解するのが難しいと思った...彼は構造体をフィールドとして使用する代わりにローカル変数として構造体を使用することについて話していたと思った。 –

1

いくつかのコードサンプルは明確に役立つかもしれない。この優れた:

// This works because you assign both fields before accessing anything 
EmpStruct empStruct; 
empStruct.SecondNumber = 2; 
empStruct.firstNumber = 1; // I made this public 
empStruct.FirstNumber = 3; 
Console.WriteLine(empStruct.FirstNumber); 
Console.WriteLine(empStruct.SecondNumber); 

// This fails because you can't use properties before assigning all the variables 
EmpStruct empStruct; 
empStruct.SecondNumber = 2; 
empStruct.FirstNumber = 3; 

// This works because you are only accessing a field that the compiler knows you've assigned 
EmpStruct empStruct; 
empStruct.SecondNumber = 2; 
Console.WriteLine(empStruct.SecondNumber); 

// This fails because you haven't assigned the field before it gets accessed. 
EmpStruct empStruct; 
Console.WriteLine(empStruct.SecondNumber); 

ポイントは、コンパイラを使用すると、フィールドを割り当てるときに何が起こるかを正確に知っている、です。しかし、プロパティを割り当てると、structの任意の数の他のフィールドにアクセスできます。コンパイラは確実にわかりません。したがって、プロパティにアクセスするには、すべてのフィールドを割り当てておく必要があります。

関連する問題