2016-06-16 6 views
1

Nehmen Sie den folgenden Code aus http://csharpindepth.com/Articles/Chapter8/PropertiesMatter.aspx:Warum verursacht die Verwendung eines Felds vs. einer automatisch implementierten Eigenschaft in C# in diesem Fall ein anderes Verhalten?

using System; 

struct MutableStruct 
{ 
    public int Value { get; set; } 

    public void SetValue(int newValue) 
    { 
     Value = newValue; 
    } 
} 

class MutableStructHolder 
{ 
    public MutableStruct Field; 
    public MutableStruct Property { get; set; } 
} 

class Test 
{  
    static void Main(string[] args) 
    { 
     MutableStructHolder holder = new MutableStructHolder(); 
     holder.Field.SetValue(10); 
     holder.Property.SetValue(10); 

     Console.WriteLine(holder.Field.Value); 
     Console.WriteLine(holder.Property.Value); 
    } 
} 

(Es gibt ein paar Kommentare im Code war ich früher verpaßt oder nicht lesen, dass ich jetzt herausgenommen habe.)

Der Anspruch auf der Artikel ist, dass der Ausgang 10 für holder.Field, aber 0 für holder.Property, und dies ist genau überprüft wurde. Ich habe ein bisschen Schwierigkeiten, warum zu sehen. Für eine automatisch implementierte Eigenschaft wird ein bestimmtes Feld reserviert, dem sie zugeordnet ist. Aufgrund der Struktur hat Property sein Hintergrundfeld sofort vollständig festgelegt und von Anfang an erstellt. Was ist der Unterschied?

+4

Sie haben bereits die Unterschiede, Sie haben sie in den Kommentaren notiert. Sie mutieren den Wert im Feld, aber Sie erhalten eine Kopie von der Eigenschaft und mutieren die Kopie. –

Antwort

5

Die Linie holder.Property eine Kopie MutableStruct zurückgibt. Wenn Sie also holder.Property.SetValue(10) schreiben, ändern Sie die Kopie, nicht das Original.

Die Linie holder.Field ist ein Alias ​​für die MutableStruct selbst.

Es ist wirklich schwer, nicht versehentlich Kopien von structs zu machen. Daher versuchen wir, sie nicht veränderbar zu machen.

+0

P. S. In meinen mehr als 14 Jahren, in denen ich mit .NET gearbeitet habe, kann ich mich nur daran erinnern, in einer Produktionsanwendung eine veränderbare Struktur zu erstellen. Und das ist, weil ich myArray.ToArray() wollte, um eine Kopie jedes Elements zu machen. –

4

Der Unterschied ist die Interjektion eines Getters für die Eigenschaft. Es ist funktional äquivalent zu

private MutableStruct _Property; 
public MutableStruct GetProperty() 
{ 
    return _Property; 
} 
public void SetProperty(MutableStruct value) 
{ 
    _Property = value; 
} 

Also, wenn Sie

holder.Field.SetValue(10); 

Sie die Struktur bei Field mutieren nennen direkt, aber wenn man

holder.Property.SetValue(10); 

rufen Sie mutieren die Kopie der Struktur zurückgegeben von GetProperty.

+0

, wenn Sie die IL Eigenschaften sehen zusammengestellt tatsächlich als Methoden 'X GET_PROPERTY()' und 'Leere set_Property (X-Wert)' ... aber Ihr Punkt ist die gleiche :) –

+2

@MatthewWhited Deshalb habe ich _functionally_ Äquivalent sagte. Die vom Compiler erzeugten Namen sind irrelevant. –