我一直在搜索,但我找不到任何方法来存储对某个变量中另一个变量的引用。 我正在尝试创建一个类来撤消用户完成的事情;
class UndoAction
{
public object var;
public object val;
public UndoAction(ref object var, object val)
{
this.var = var;
this.val = val;
}
public static List<UndoAction> history = new List<UndoAction>();
public static void AddHistory(ref object var, object val)
{
history.Add(new UndoAction(ref var, val));
}
}
我想你可以看到我在这里想要实现的目标。
我跑的问题;
this.var = var;
不存储引用,而是存储引用的'var'的值。 如何存储引用本身,所以我可以简单地运行;
this.var = val;
在我的情况下,“撤消”一个动作?
答案 0 :(得分:10)
标准安全C#根本不支持此功能。底层框架几乎包含所有必要的概念,但它们并未在C#语言中公开。但即使这样,这样的参考也不能存储在一个字段中。
您可以拥有的最好的方法是将其包装在使用委托的某个类中。相比之下,这显然相当昂贵,但除非您在紧密循环中修改内容,否则这可能就足够了:
class VarRef<T>
{
private Func<T> _get;
private Action<T> _set;
public VarRef(Func<T> @get, Action<T> @set)
{
_get = @get;
_set = @set;
}
public T Value
{
get { return _get(); }
set { _set(value); }
}
}
然后像这样使用它:
var myVar = ...
var myVarRef = new VarRef<T>(() => myVar, val => { myVar = val; });
...
myVarRef.Value = "47";
Console.WriteLine(myVar); // writes 47
答案 1 :(得分:1)
你走错了方向。 Boxing / Unboxing不是您需要的,您需要保存对象引用和特定属性以及该属性的值。
不要试图建立一个可以撤销人类创造的完全通用的系统。 从简单开始。
首先使用像...... IUndoable这样的界面设置某些对象。
使用[UnduableProperty]等属性标记某些属性 使用INotifyPropertyChange接口并使用PropertyChanged事件。 当属性发生变化时,请听取它,检查它是否可以撤消,并保存其值。
不要害怕使用反射,但如果可以解决速度问题,请尽量避免使用反射。
保存对象,保存属性,保存值。 创建管理器对象以管理撤消过程。
如果您在保存复杂结构的值时遇到问题,请不要忘记ISerializable。
祝你好运。答案 2 :(得分:-1)
在C#中,从对象继承的每个类都是引用类型。
这意味着除非您将显式克隆该对象,否则您将只有引用而不是新对象。
this.var = var; # <- that actually gets the reference to var, and not clones the object.
如果你看到this.var持有该对象是因为环境隐藏了你并且你不必知道参考地址本身。