2012-05-23 18 views
5

Szukałem trochę, ale nie mogę znaleźć żadnego sposobu przechowywania odniesienia do innej zmiennej w pewnej zmiennej. Próbuję zrobić zajęcia, aby cofnąć rzeczy wykonane przez użytkownika;Przechowuj odwołanie w innej zmiennej

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

Myślę, że można zobaczyć, co staram się osiągnąć tutaj.

Problem, który prowadziłem;

this.var = var; 

nie przechowuje odwołanie, ale wartość wskazanej „var”. Jak mogę zapisać referencję, więc mogę po prostu uruchomić;

this.var = val; 

do "cofnąć" działanie, w moim przypadku?

+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

Odpowiedz

8

Standardowy sejf C# nie obsługuje tego w ogóle. Podstawowa struktura ma prawie wszystkie niezbędne pojęcia, ale nie są one ujawnione w języku C#. Ale nawet wtedy takie odniesienie nie może być przechowywane w polu.

Najlepsze, co możesz mieć, to owinąć ją w klasę, która używa delegatów. Jest to oczywiście dość drogie w porównaniu, ale jeśli nie jesteś modyfikowanie rzeczy w ciasnej pętli może to być wystarczająco dobre: ​​

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

a następnie używać go tak:

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

... 

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

W języku C#, każda klasa dziedziczący z obiektu będzie typem referencyjnym.

oznacza to, że dopóki nie zostanie wyraźnie sklonowany obiekt, będziesz miał tylko odniesienie, a nie nowy obiekt.

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

jeśli widzisz, że this.var trzyma przedmiot jest ponieważ środowisko ukrywa ją od siebie i nie trzeba znać sam adres odniesienia.

1

Twoje postępowanie w niewłaściwy sposób. Boks/Unboxing nie jest tym, czego potrzebujesz, musisz zapisać odniesienie do obiektu i konkretną właściwość oraz wartość tej właściwości.

Nie próbuj tworzyć w pełni generycznego systemu, który może cofnąć powstanie rasy ludzkiej. Uruchom proste.

Zacznij od ustawienia pewnych obiektów za pomocą interfejsu takiego jak ... IUndoable.

jako pewne właściwości z atrybutami jak [UnduableProperty] używać interfejsu INotifyPropertyChange i użyć zdarzenia PropertyChanged. Po zmianie właściwości należy ją odsłuchać, sprawdzić, czy nie można jej wyjąć, i zapisać jej wartość.

Nie bój się korzystać z refleksji, ale staraj się tego unikać, jeśli możesz na problemy z szybkością.

Zapisz obiekt, zapisz właściwość, zapisz wartość. Utwórz obiekt menedżera, aby zarządzać procesem cofania.

Jeśli masz problemy z zapisaniem wartości złożonych struktur, nie zapomnij o ISerializable.

Powodzenia.

Powiązane problemy