andy840119/Object.Undo

Editable object should not support the struct.

Opened this issue · 1 comments

Here's the reason:

Here's the code for change the property in the editable object.

public class PropertyChangeAction<TProperty>
{
    private readonly IEditableObject obj;
    private readonly string propertyName;
    private readonly TProperty? oldValue;
    private readonly TProperty? newValue;

    public PropertyChangeAction(IEditableObject editableObject, string propertyName, TProperty? value)
    {
        obj = editableObject;
        this.propertyName = propertyName;

        // should backup the current value.
        var propertyInfo = getPropertyInfo(obj, propertyName);
        oldValue = (TProperty)propertyInfo.GetValue(obj);
        newValue = value;

        // perform the action after method call.
        Redo();
    }

    public void Undo()
    {
        var propertyInfo = getPropertyInfo(obj, propertyName);
        Undo(obj, propertyInfo, oldValue);
    }

    public void Redo()
    {
        var propertyInfo = getPropertyInfo(obj, propertyName);
        Redo(obj, propertyInfo, newValue);
    }

    private static PropertyInfo getPropertyInfo(IEditableObject obj, string propertyName)
        => obj.GetType().GetProperties().Single(x => x.Name == propertyName);

    protected virtual void Undo(IEditableObject editableObject, PropertyInfo propertyInfo, TProperty? property)
    {
        propertyInfo.SetValue(editableObject, property);
    }

    protected virtual void Redo(IEditableObject editableObject, PropertyInfo propertyInfo, TProperty? property)
    {
        propertyInfo.SetValue(editableObject, property);
    }
}

Here's the code using the change:

[Test]
public void TestUndoRedoPropertyInStruct()
{
    var obj = new EditableObjectStruct
    {
        TestProperty = "test",
    };
    var action = new PropertyChangeAction<string>(obj, nameof(EditableObjectStruct.TestProperty), "test2");

    Assert.AreEqual("test2", obj.TestProperty);
    action.Undo();
    Assert.AreEqual("test", obj.TestProperty);
}

image
And we can see that the EditableObjectStruct in the PropertyChangeAction has been copied.

Guess we should not support the structure.

Maybe we can revert some changes in the #3:

  1. Remove that stupid guid property in the interface.
  2. change in interface into the property because property is more eye-friendly.