3

このコードをコンパイルするとエラーが発生します。

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 が参照型になっているように見えます (イベント メンバーなしでは正常に動作します)。何が起こっている?

4

3 に答える 3

14

C# では、すべてのフィールドを初期化する場合を除き、コンストラクターを呼び出すために構造体を「新規作成」する必要があります。EventHandler メンバー 'trigger' を未割り当てのままにしました。

「トリガー」に割り当てるか、次を使用してみてください。

Vector2 vector = new Vector2()

新しいオブジェクトはヒープに割り当てられず、関数スタックに割り当てられたままです。

MSDNを引用するには:

new 演算子を使用して構造体オブジェクトを作成すると、それが作成され、適切なコンストラクターが呼び出されます。クラスとは異なり、構造体は new 演算子を使用せずにインスタンス化できます。new を使用しない場合、フィールドは未割り当てのままになり、 すべてのフィールドが初期化されるまでオブジェクトを使用できません。

于 2008-11-18T00:38:59.930 に答える
2

他の人がこれを回避する方法を説明していますが、コードのもう 1 つの大きな大きな問題に言及する価値があると思います: 変更可能な構造体があります。それらはほとんど常に悪い考えです。これは、そのままにしておくと遭遇する多くの問題の最初の 1 つに過ぎません。

不変にするか、クラスにすることを強くお勧めします。

于 2008-11-18T06:32:10.827 に答える
1

Rob Walker はより良い反応を示しました。なぜなら、彼はドキュメントから始めてからコードを推論したからです (私は逆に行ったのに対して)。

initobjトリガー フィールドをコメント アウトしてサンプル コードをコンパイルし、IlAsm を実行して結果の MSIL を取得すると、ローカル変数ベクトルのオペコードがないことがわかります。

構造体に値型のみが含まれているinitobj場合は、 がなくても問題ありません。Vector2結局のところ、それらは単なる生の記憶です。ただし、Vector2構造体に参照も含まれている場合は、初期化されていないオブジェクト参照が発生するのを防ぐために、構造体を初期化する必要があります。

部分的に初期化されたオブジェクトを返さないようにするには、triggerイベント ハンドラーに明示的に書き込むか、新しい操作でオブジェクト全体を初期化する必要があります。ただし、構造体が参照型になることはありません。

于 2008-11-18T00:53:13.817 に答える