3 Stimmen

Warum bekomme ich diesen Fehler beim Erstellen und Zurückgeben einer neuen Struktur?

Ich erhalte einen Fehler, wenn ich diesen Code kompiliere:

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'
    }
}

Hallo!

Der Compiler sagt: "Use of unassigned local variable 'vector'" und verweist auf den Rückgabewert. Für mich sieht es so aus, als ob Vector2 zu einem Referenztyp wird (ohne das Event-Member verhält er sich normal). Was ist passiert?

0 Stimmen

Die Erstellung von Strukturen mit veränderlichen Mitgliedern ist riskant. Verwenden Sie entweder eine Klasse, oder markieren Sie die Felder als "readonly".

14voto

Rob Walker Punkte 45267

In C# müssen Sie immer noch 'new' für eine Struktur verwenden, um einen Konstruktor aufzurufen, es sei denn, Sie initialisieren alle die Felder. Sie haben das EventHandler-Mitglied 'trigger' nicht zugewiesen.

Versuchen Sie entweder die Zuweisung zu 'Trigger' oder die Verwendung:

Vector2 vector = new Vector2()

Das neue Objekt ist no auf dem Heap zugewiesen wird, wird sie dennoch auf dem Funktionsstapel zugewiesen.

Um zu zitieren MSDN :

Wenn Sie ein struct-Objekt mit den new-Operator, wird es erstellt und der entsprechende Konstruktor wird aufgerufen. Im Gegensatz zu Klassen können Structs instanziiert werden, ohne den new Operator instanziiert werden. Wenn Sie nicht neu verwenden, die Felder bleiben unbelegt und die Objekt kann nicht verwendet werden bis alle Felder initialisiert sind.

0 Stimmen

Sie sollten in der Lage sein, es auf null zu initialisieren

1 Stimmen

Ich möchte meine Ereignisse auf '= delegate { };' initialisieren, damit ich beim Auslösen des Ereignisses keine Nullprüfung durchführen muss.

2voto

Jon Skeet Punkte 1325502

Andere haben erklärt, wie man das umgehen kann, aber ich denke, es lohnt sich, das andere große, große Problem mit Ihrem Code zu erwähnen: Sie haben eine veränderbare Struktur. Diese sind ziemlich genau immer eine schlechte Idee. Das wird nur das erste von vielen Problemen sein, auf die Sie stoßen werden, wenn Sie es so halten.

I stark empfehlen, dass Sie es entweder unveränderlich machen oder eine Klasse daraus machen.

0 Stimmen

Ich unterstütze das nachdrücklich - mutable structs immer mehr Schmerzen verursachen, als die Menschen erwarten.

1voto

Kennet Belenky Punkte 2715

Rob Walker hat eine bessere Antwort, da er von den Dokumenten ausgegangen ist und dann zum Code übergegangen ist (während ich den umgekehrten Weg gegangen bin).

Wenn Sie den Beispielcode mit auskommentiertem Triggerfeld kompilieren und dann IlAsm ausführen, um die resultierende MSIL zu erhalten, werden Sie sehen, dass es keine initobj Opcode für den lokalen Variablenvektor.

Das Fehlen von initobj ist in Ordnung, wenn die Vector2 Struktur enthält nur Wertarten. Sie sind ja schließlich nur Rohspeicher. Wenn jedoch die Vector2 Struktur ebenfalls einen Verweis enthält, muss dieser initialisiert werden, um zu verhindern, dass ein nicht initialisierter Objektverweis vorliegt.

Um die Rückgabe eines teilweise unitialisierten Objekts zu vermeiden, müssen Sie in die trigger Ereignisbehandler explizit an, oder initialisieren Sie das gesamte Objekt durch eine neue Operation. In keinem Fall wird die Struktur jedoch in einen Referenztyp umgewandelt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X