2009-12-02 17 views
0

我試圖在C#中的AtomicReference類,我想保持田間參考保護,但我還需要在GET方法返回值:C#如何保護原子類的字段?

class AtomicReference 
{ 
    private Object _value; 

    public AtomicReference() 
    { 
     _value = new Object(); 
    } 

    public AtomicReference(Object value) 
    { 
     OptimisticSet(value); 
    } 

    public Object CompareAndSet(Object newValue) 
    { 
     return Interlocked.Exchange(ref _value, newValue); 
    } 

    public void OptimisticSet(Object newValue) 
    { 
     do { 
     } while (_value == Interlocked.CompareExchange(ref _value, _value, newValue)); 
    } 

    public Object Get() 
    { 
     // Don't leak the field reference 
     const Object constVal = _value; 
     return constVal; 
    } 
} 

這是一個有點笨拙的方式圍繞着這個問題......我不能只將該字段設置爲只讀,因爲我需要能夠設置它。有比我更好的解決方案嗎?

更新: 感謝您的快速響應! 正確地指出,如果我簡單地返回_value,那麼引用將受到保護。我也想保護_value的變異。如果我允許_value在AtomicReference之外進行變異,那麼它會破壞創建這個類的整個目的......是否有辦法實現這個目標?

+1

爲什麼會有java標籤? – SLaks

+0

我剛拿出java標籤 – Suppressingfire

+1

這個java標籤的意思是我想獲得與Java的AtomicReference類似的功能。 – Kiril

回答

3

即使您嘗試,也無法返回對C#中的字段(不帶不安全的代碼)或Java的引用。 (我不是指一個對象的引用)

你可以簡單地寫return _value;你的調用者將不能寫入字段。

+1

的確,調用者不能將_value本身更改爲引用不同的對象,但調用者是否可以改變_value引用的對象?例如,如果object實際上是Square的類型,調用者將能夠執行'obj.Side ++'。我對這個問題的理解是他希望避免這種突變。 –

+1

如果是這樣,他運氣不好;這是不可能的。 (除非你限制爲值類型或'IClonable')從他接受答案這一事實,我想他並不是。 – SLaks

+0

是的,我重讀了這個樣本,看起來他只關心引用。 –

2

C#不支持C++的const關鍵字,該關鍵字允許對可變對象進行不可變的引用。

只有兩種方法可以做你想問的問題。

  • 您可以在每次返回時克隆該對象。請注意,這隻適用於可克隆的對象,並且會很慢。
  • 您只能支持值類型。
+0

謝謝!我很抱歉,我無意間想到了兩個不同的想法......我正在考慮將一個Int32/Int64傳遞給AtomicReference類,完全消除了正確的方法是使用AtomicInteger。 – Kiril

相關問題