2017-04-25 46 views
0

在C#中,我希望能夠在一個作用域的末尾恢復一個對象的原始值。以與this question類似的方式,但對於C#。有沒有辦法在c#中的範圍內備份/恢復值?

對此問題的一個答案表明使用boost的state_saver,我相信它使用RAII來備份和恢復原始值。

通過實現IDisposable,您可以在c#中獲得RAII。

這是一次嘗試。這不是很有效,因爲當你將RefObject設置爲一個新值時,它會丟失對原始值的引用。而且你不能在POD上使用它。

不起作用

public class State_Saver<T> : IDisposable 
{ 
    public State_Saver(ref T obj, T newValue) 
    { 
     RefObject = obj; 
     m_Backup = RefObject; 

     RefObject = newValue; 
    } 

    public void Dispose() 
    { 
     RefObject = m_Backup; 
    } 

    private T RefObject; 
    private T m_Backup; 
} 

可以得到它,如果我補充一點,T類型的對象被包裹在某種包裝類的要求工作。但它比我想強加給使用這個類的人更多一點體重

作品

public class ValueWrapper<T> 
{ 
    public ValueWrapper(T value) 
    { 
     this.Value = value; 
    } 

    public T Value { get; set; } 
} 

public class ScopedBackup<T> : IDisposable 
{ 
    public ScopedBackup(ref ValueWrapper<T> obj, T newValue) 
    { 
     RefObject = obj; 
     m_Backup = RefObject.Value; 

     RefObject.Value = newValue; 
    } 

    public void Dispose() 
    { 
     RefObject.Value = m_Backup; 
    } 

    private ValueWrapper<T> RefObject; 
    private T m_Backup; 
} 

用法:

ValueWrapper<bool> fred = new ValueWrapper<bool>(true); 

Debug.WriteLine(fred.Value); // writes true 

using (new ScopedBackup<bool>(ref fred, false)) 
{ 
    Debug.WriteLine(fred.Value); // writes false 
} 

Debug.WriteLine(fred.Value); // writes true 

有沒有更好的辦法做到這一點比這個?

感謝

+0

我不認爲你可以做得更好(因爲你不能在一個字段中存儲引用(ref))。也許只是使用try-finally而沒有額外的複雜性? – Evk

+0

您可能對['IEditableObject'](https://msdn.microsoft.com/en-us/library/system.componentmodel.ieditableobject(v = vs.110).aspx)界面感興趣。它不能解決你的問題,但它確實與你的用例很好地對應。 –

回答

0

而不是使用using使用lambda的。所以你得到這樣的代碼

ValueWrapper<bool> fred = new ValueWrapper<bool>(true); 

Debug.WriteLine(fred.Value); // writes true 

ScopedBackup.Do<bool>(ref fred, false,()=>{ 

    Debug.WriteLine(fred.Value); // writes false 
}); 

Debug.WriteLine(fred.Value); // writes true 

(該代碼是一個粗略的草圖,但我希望你明白了)。這樣做的原因是呼叫者可以選擇不使用using,它的可選項。在這裏沒有選擇

相關問題