2014-09-26 8 views
7

Ok, lassen Sie uns einen Code haben:IList <mutable_struct> vs mutable_struct []

//I complie nicely 
ValueType[] good = new ValueType[1]; 
good[0].Name = "Robin"; 

//I don't compile: Cannot modify expression because its not a variable 
IList<ValueType> bad = new ValueType[1]; 
bad[0].Name = "Jerome"; 

struct ValueType 
{ 
    public string Name; 
} 

Was genau hinter den Kulissen vor sich geht, die der Compiler verursacht sträuben?

//Adding to watch the following 
good.GetType().Name //Value = "ValueType[]" It's a ValueType array. 
bad.GetType().Name //Value = "ValueType[]" Also a ValueType array. 

Der Compiler hindert mich von einem Mitglied der Kopie des Objekts zu modifizieren möchte ich ändern. Aber warum wird eine Kopie von diesem Array erstellt?

Ein wenig mehr Forschung wirft:

var guess = (ValueType[]) bad; 
guess[0].Name="Delilah"; 

Nun, was denken Sie bad[0].Name ist? Das ist richtig, es ist "Delilah".

+1

Der Compiler ist großzügig, es hindert Sie daran, eine Kopie von 'Name' zu ​​verändern. Sehen Sie sich [Struct Variable in einem Dictionary ändern] an (http://stackoverflow.com/questions/6255305/modify-struct-variable-in-a-dictionary) –

+0

@YuvalItzchakov ja, es ist sehr hilfreich. Warum wird es im zweiten Fall kopiert, aber nicht im ersten? – Robino

+0

Das qn, mit dem Sie verbunden waren, war bereits uplooted. Es macht jedoch sehr offensichtlich eine Kopie des Werttyps. In meinem Beispiel fühlt es sich etwas subtiler an. – Robino

Antwort

7

Warum ist ein Wert von der Art ist, IList<ValueType>-Kopie zurückgegeben, aber nicht aus dem Array

Da ein Array an den Compiler ein Einbau-Konstrukt bekannt ist. Sein Operator [] hat eine eingebaute Semantik, die dem Compiler eine änderbare Referenz innerhalb des Arrays selbst bereitstellt.

Wenn der Compiler eine Schnittstelle behandelt, weiß er andererseits, dass er eine Kopie eines Werttyps zurückbekommt, den Sie zu ändern versuchen. Mit anderen Worten sieht der Compiler ILists Operator und den Operator des Arrays anders an.

Hinweis: Es ist selbstverständlich, dass diese Übung von rein akademischem Wert ist, weil mutable structs are evil.

+0

Die gängigen veränderbaren Referenztypen sind genauso schlecht, nur auf etwas andere Art und Weise. – CodesInChaos