2017-04-25 87 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,它的可选项。在这里没有选择

相关问题