&の作成時にこのエラーが発生するのはなぜですか。新しい構造体を返しますか?
-
08-07-2019 - |
質問
このコードをコンパイルするとエラーが発生します:
using System;
public struct Vector2
{
public event EventHandler trigger;
public float X;
public float Y;
public Vector2 func()
{
Vector2 vector;
vector.X = 1;
vector.Y = 2;
return vector; // error CS0165: Use of unassigned local variable 'vector'
}
}
こんにちは!
コンパイラは、「割り当てられていないローカル変数 'vector'を使用」"と言います。戻り値を指します。 Vector2は参照型になるように見えます(イベントメンバーがなければ、Vector2は正常に動作します)。何が起きているのですか?
解決
C#では、フィールドを all で初期化しない限り、コンストラクターを呼び出すために構造体を「新規」にする必要があります。 EventHandlerメンバー「トリガー」は割り当てられていません。
「トリガー」に割り当てるか、以下を使用してください:
Vector2 vector = new Vector2()
新しいオブジェクトはヒープに割り当てられない、関数スタックに割り当てられます。
MSDN を引用するには:
を使用して構造体オブジェクトを作成する場合 新しい演算子、作成され、 適切なコンストラクターが呼び出されます。 クラスとは異なり、構造体は 新しいを使用せずにインスタンス化 オペレーター。 新規を使用しない場合 フィールドは未割り当てのままになり、 オブジェクトはすべて使用するまで使用できません フィールドが初期化されます。
他のヒント
他の人はこれを回避する方法を説明しましたが、あなたのコードに関する他の大きな、大きな問題に言及する価値があると思います:あなたは可変構造を持っています。これらはほとんど常に悪い考えです。これは、そのままにしておくと遭遇する多くの問題の最初のものに過ぎません。
不変にするか、クラスにすることを強くお勧めします。
Rob Walkerは、ドキュメントから始めてからコードを推論したので、より良い応答が得られました(一方、私は逆になりました)。
トリガーフィールドをコメントアウトしてサンプルコードをコンパイルし、IlAsmを実行して結果のMSILを取得すると、ローカル変数ベクトルの initobj
オペコードがないことがわかります。
initobj
の欠如は、 Vector2
構造に値型のみが含まれる場合は問題ありません。結局のところ、それらは単なる生メモリです。ただし、 Vector2
構造体にも参照が含まれる場合は、初期化されていないオブジェクト参照を防ぐために初期化する必要があります。
部分的に単一化されたオブジェクトが返されないようにするには、 trigger
イベントハンドラに明示的に書き込むか、新しい操作でオブジェクト全体を初期化する必要があります。ただし、どのような場合でも構造は参照型になりません。