A minap épp egy immutable-nek szánt típust írtam, és nem voltam megelégedve azzal, amit alkottam. Én ugyanis úgy tudtam, hogy a readonly
módosító nem használható propertykre a C# nyelvben. Ezt jól is tudtam, azonban ennek következményeként a következő kódot írtam:
public class ImmutableThing {
public string Somehing { get; private set; }
public ImmutableThing(string something){
// This assignment is valid, as desired.
this.Something = something;
}
public void Example(){
Something = "Unfortunately this is totally valid now, despite my desire to write an Immutable datastructure.";
}
}
Ez azonban nem csak nekem nem tetszett, de egy kollégámnak sem, aki a review során felvilágosított (az enyémmel egybevágó) aggályáról: a private set
bármely metódusból használható a típuson belül. Védelmemre csak azt tudtam felhozni, hogy na igen, de a konstruktorból be kell tudjam állítani, ezért nem lehet readonly
. Arra pedig hadd ne írjak readonly
mezőket mögé, hogy csak egyszer lehessen értékül adni, inkább majd a reviewkon a jövőben is ilyen alaposak leszünk, és figyelünk. Kiváló kollégám ezt nem tudta elfogadni, de egyből segítségemre is sietett: egy (számomra) újdonságot mutatott a nyelvben!
public class ImmutableThing {
public string Somehing { get; }
public ImmutableThing(string something){
// this assignment is still valid!
this.Something = something;
}
public void Example(){
Something = "This is now impossible. This line prevents compiling this code! This is what I want!";
}
}
Jól látható, hogy private set
eltávolításra került. A kód azonban így is lefordul! Amennyiben ugyanis egy setter nélküli propertynek akarunk értéket adni, azt csak és kizárólag a konstruktorból tehetjük meg. Ezzel gyakorlatilag a readonly
mezőével azonos viselkedést kapunk. Ezzel egyet kihúzhatok a nyelv furcsállott tulajdonságai közül.
Ezek után tudatlanságomra csak egy mentségem van: A dokumentációt olvasva (a cikk írásakori állapotában) nem találtam utalást erre a fontos és releváns működési módra.