2012-05-23 12 views
5

He estado buscando un poco, pero no puedo encontrar ninguna forma de almacenar una referencia a otra variable en una determinada variable. Estoy tratando de hacer una clase para deshacer las cosas hechas por el usuario;Almacenar una referencia en otra variable

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

Supongo que puede ver lo que estoy tratando de lograr aquí.

Problema que corrí;

this.var = var; 

no almacena la referencia, pero el valor de la referencia 'var'. ¿Cómo puedo almacenar la referencia en sí misma, así puedo simplemente ejecutarla?

this.var = val; 

para "deshacer" una acción, en mi caso?

+1

http://stackoverflow.com/a/4543089 – dtb

+1

http://stackoverflow.com/a/6346059 – dtb

+1

http://blogs.msdn.com/b/ericlippert/archive/2011/06/23/ref -returns-and-ref-locals.aspx – dtb

Respuesta

8

La caja fuerte estándar C# no es compatible con esto. El marco subyacente tiene casi todos los conceptos necesarios, pero no están expuestos en el lenguaje C#. Pero incluso entonces, dicha referencia no puede almacenarse en un campo.

Lo mejor que puedes tener es envolverlo en alguna clase que use delegados. Obviamente, esto es bastante caro en comparación, pero a menos que esté modificando cosas en un bucle estrecho esto podría ser lo suficientemente bueno:

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

y luego usarlo como esto:

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

... 

myVarRef.Value = "47"; 
Console.WriteLine(myVar); // writes 47 
0

En C#, todas las clases que hereda de un objeto será un tipo de referencia.

eso significa que a menos que clones explícitamente el objeto, solo tendrás la referencia y no un objeto nuevo.

this.var = var; # <- that actually gets the reference to var, and not clones the object. 

si ves que this.var sostiene el objeto se debe a que el entorno lo esconde de usted y usted no tiene que saber la dirección de referencia en sí.

1

Va por mal camino. Boxeo/Unboxing no es lo que necesita, debe guardar la referencia del objeto y la propiedad específica, y el valor de esa propiedad.

No intente crear un sistema completamente genérico que pueda deshacer la creación de la raza humana. Comience simple.

Comience configurando ciertos objetos con una interfaz como ... IUndoable.

Marcar ciertas propiedades con un atributo como [UnduableProperty] Utilice la interfaz INotifyPropertyChange y utilice el evento PropertyChanged. Cuando una propiedad cambia, escúchala, verifica si se puede deshacer y guarda su valor.

No tenga miedo de usar la reflexión, pero trate de evitarla si puede por problemas de velocidad.

Guarde el objeto, guarde la propiedad, guarde el valor. Crea un objeto de administrador para administrar el proceso de deshacer.

Si tiene problemas para guardar el valor de las estructuras complejas, no se olvide de ISerializable.

Buena suerte.

Cuestiones relacionadas