Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Store a reference in another variable

Tags:

c#

.net

reference

I've been searching around a bit, but I can't find any way to store a reference to another variable in a certain variable. I'm trying to make a class to undo things done by the user;

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));
    }
}

I guess you can see what I'm trying to achieve here.

The problem I ran on;

this.var = var;

doesn't store the reference, but the value of the referenced 'var'. How can I store the reference itself, so I can simply run;

this.var = val;

to "undo" an action, in my case?

like image 420
Tgys Avatar asked May 23 '12 18:05

Tgys


2 Answers

Standard safe C# does not support this at all. The underlying framework has almost all of the necessary concepts, but they aren't exposed in the C# language. But even then, such a reference can't be stored in a field.

The best you can have is to wrap it in some class that uses delegates. This is obviously rather expensive in comparison, but unless you are modifying things in a tight loop this might be good enough:

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); }
    }
}

And then use it like this:

var myVar = ...
var myVarRef = new VarRef<T>(() => myVar, val => { myVar = val; });

...

myVarRef.Value = "47";
Console.WriteLine(myVar); // writes 47
like image 142
Roman Starkov Avatar answered Oct 10 '22 14:10

Roman Starkov


Your going about it the wrong way. Boxing/Unboxing isn't what you need, you need to save the object reference and the specific property, and that property's value.

Don't try to make a fully generic system that can undo creation of the human race. Start simple.

Start by setting certain objects with an interface like... IUndoable.

Mark certain properties with an attribute like [UnduableProperty] Use the INotifyPropertyChange interface and use the PropertyChanged event. When a property changes, listen to it, check if it's undoable, and save its value.

Don't be afraid to use reflection but try to avoid it if you can for speed issues.

Save the object, save the property, save the value. Create a manager object to manage the undo process.

If you are having trouble saving the value of complex structs, don't forget about ISerializable.

Good luck.

like image 26
Erez Robinson Avatar answered Oct 10 '22 16:10

Erez Robinson