2011-12-25 78 views
-1

我希望能夠提供我的課之一,「默認」值或狀態。我們將調用該類Foo,它看起來像這樣:如何防止一個只讀的對象引用從修改只讀對象?

class Foo 
{ 
    public static readonly Default = new Foo() { Bar = 42 }; 
    public int Bar { get; set; } 
} 

它說的是,我要的Foo實例的默認值有它的成員,Bar,設置爲42時出現問題的時候我修改了對Foo.Default的引用。

void Function() 
{ 
    Foo temp = Foo.Default; 
    temp.Bar = 101; // Foo.Default.Bar = 101 

    Foo anothertemp = Foo.Default; // anothertemp.Bar = 101!! 
} 

我該如何避免這種行爲?

回答

1

Foo不變。

public class Foo 
{ 
    public static readonly Foo Default = new Foo(42); 

    public Foo(int bar) 
    { 
     Bar = bar; 
    } 

    public int Bar { get; private set; } 
} 

暴露字段在大多數情況下被認爲是不好的做法,因爲它破壞了封裝。

-1

你得讓你在那裏通過構造方法設置酒吧特殊的子類,然後二傳手拋出一個異常,或者乾脆忽略設置。

public class Foo { 
    public Foo() { } 

    public virtual int Bar { get { return _bar; } set { _bar = value; } } 
} 

public class ReadonlyFoo : Foo { 
    public ReadonlyFoo(int bar) { _bar = bar; } 

    public override int Bar { get { return _bar; } set { } } 
} 

雖然我並不真的推薦這個;它揮發了Liskov substitution principle

+2

更簡單地說,它違反了什麼每個人都希望'set'做。 – jason 2011-12-25 21:55:36

+0

這可能是,但它回答了這個問題。你低估了,因爲你不喜歡我的推理不推薦這樣做? – Andy 2011-12-27 01:25:25

+0

對不起,雖然這個答案在技術上可能是正確的,但這是一個不好的做法。你自己說過你不建議這樣做。 – jason 2011-12-27 02:53:03

1

爲此,我建議:

public static Foo Default { get { return new Foo(){ Bar = 42 }; }}

如果任何ACCE改變默認值,其它配件可以使用默認值(但不註明出處!)

+1

+1。如果Foo必須是可變的,這是一個不錯的選擇。我可能會讓它命名CreateWithDefaults靜態工廠方法()或一些這樣做很明顯的呼叫者,它創建了一個新的實例每次。 – TrueWill 2011-12-25 22:32:39