Frage

Treten um einige kleine Strukturen, während die Beantwortung href="https://stackoverflow.com/questions/414981/directly-modifying-listt-elements">, stieß ich auf das folgende unerwartet:

Die folgende Struktur, ein int Feld verwendet, ist vollkommen legal:

struct MyStruct
{ 
    public MyStruct ( int size ) 
    { 
        this.Size = size; // <-- Legal assignment.
    } 

    public int Size; 
}

Allerdings ist die folgende Struktur, eine automatische Eigenschaft mit nicht kompiliert:

struct MyStruct
{ 
    public MyStruct ( int size ) 
    { 
        this.Size = size; // <-- Compile-Time Error!
    } 

    public int Size{get; set;}
}

Der Fehler zurückgegeben wird, ist „Das‚this‘Objekt kann nicht vor werden alle ihre Felder zugewiesen werden“. Ich weiß, dass dies ist die übliche Verfahren für eine Struktur: das Trägerfeld für jede Eigenschaft zugeordnet werden muß direkt (und nicht über das Set-Accessor Eigentum) aus der Konstruktor der Struktur.

Eine Lösung ist eine explizite Unterstützung Feld zu verwenden:

struct MyStruct
{ 
    public MyStruct(int size)
    {
        _size = size;
    }

    private int _size;

    public int Size
    {
        get { return _size; }
        set { _size = value; }
    }
}

(Beachten Sie, dass VB.NET würde dieses Problem nicht haben, weil in VB.NET alle Felder automatisch auf 0 / null initialisiert / falsch, wenn zum ersten Mal erstellt.)

Dies scheint eine unglückliche Einschränkung zu sein, wenn sie mit structs in C # mit automatischen Eigenschaften. Denken konzeptionell, ich frage mich, ob dies nicht ein angemessener Ort für es wäre eine Ausnahme zu sein, dass die Eigenschaft set-Accessor ermöglicht innerhalb einer Struktur Konstruktor, zumindest für eine automatische Eigenschaft aufgerufen werden?

Dies ist ein kleines Problem, fast ein kanten Fall, aber ich frage mich, was andere dachten darüber ...

War es hilfreich?

Lösung

Von C # 6 weiter: Das ist kein Problem mehr


becore C # 6, müssen Sie den Standard-Konstruktor für diese aufrufen zu arbeiten:

public MyStruct(int size) : this()
{
    Size = size;
}

Ein größeres Problem hier ist, dass man eine veränderbare Struktur hat. Dies ist nie eine gute Idee. Ich würde es machen:

public int Size { get; private set; }

Nicht technisch unveränderlich, aber nahe genug.

Mit dem jüngsten Versionen von C #, können Sie auf diesem verbessern:

public int Size { get; }

Dies kann nun nur im Konstruktor zugewiesen werden.

Andere Tipps

Sie können dieses Problem beheben, indem man zuerst den Standard-Konstruktor aufrufen:

struct MyStruct 
{
    public MyStruct(int size) : this() 
    {
        this.Size = size; // <-- now works
    }

     public int Size { get; set; }
}

Eine weitere obskure Behelfslösung für dieses Problem eine in der temporären Tuple Klasse in der Extensibility Framework Managed (via Krzysztof Kozmic ):

public struct TempTuple<TFirst, TSecond>
{
    public TempTuple(TFirst first, TSecond second)
    {
        this = new TempTuple<TFirst, TSecond>(); // Kung fu!
        this.First = first;
        this.Second = second;
    }

    public TFirst First { get; private set; }
    public TSecond Second { get; private set; }

(Der vollständige Quellcode von Codeplex: Tuple.cs )

Ich stelle auch fest, dass die Dokumentation für CS0188 wird aktualisiert, um hinzufügen:

  

Wenn Sie sehen, diesen Fehler, wenn sie versuchen zu   eine Eigenschaft in einer Struktur initialisieren   Konstruktor, die Lösung zu ändern   der Konstruktor Parameter angeben   das Trägerfeld statt der   Immobilien-Objekt selber. Auto-implementiertes   Eigenschaften sollten in vermeiden   structs weil sie keine Unterstützung   Feld und kann daher nicht sein   in irgendeiner Weise von der initialisierte   Konstruktor.

Also nehme ich das bedeuten, dass die offizielle Führung ist im alten Stil Eigenschaften in Ihrem structs zu verwenden, wenn Sie dieses Problem zulaufen, was wahrscheinlich weniger dunkel (und mehr readible) als jede der beiden anderen Alternativen erforschen so weit.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top