Last active
May 14, 2019 21:03
-
-
Save spixy/e51937de63d1a6fde7d01a7043e93d8f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Undo : IDisposable | |
{ | |
private readonly Action _undoFunc; | |
private static Action CreateUndoFunc<TResult>(object obj, MemberInfo memberInfo, TResult newValue) | |
{ | |
TResult oldValue; | |
switch (memberInfo) | |
{ | |
case FieldInfo fieldInfo: | |
oldValue = (TResult)fieldInfo.GetValue(obj); | |
fieldInfo.SetValue(obj, newValue); | |
return () => { fieldInfo.SetValue(obj, oldValue); }; | |
case PropertyInfo propertyInfo: | |
oldValue = (TResult)propertyInfo.GetMethod.Invoke(obj, Array.Empty<object>()); | |
propertyInfo.SetMethod.Invoke(obj, new object[] { newValue }); | |
return () => { propertyInfo.SetMethod.Invoke(obj, new object[] { oldValue }); }; | |
default: | |
throw new Exception("Only property and field expressions are supported"); | |
} | |
} | |
/// <summary> | |
/// Create Undo for static object | |
/// </summary> | |
public static Undo Create<TResult>(Expression<Func<TResult>> propertyFunc, TResult newValue) | |
{ | |
MemberInfo memberInfo = (propertyFunc.Body as MemberExpression)?.Member; | |
Action undoFunc = CreateUndoFunc(null, memberInfo, newValue); | |
return new Undo(undoFunc); | |
} | |
/// <summary> | |
/// Create Undo for instance object | |
/// </summary> | |
public static Undo Create<T, TResult>(T obj, Expression<Func<T, TResult>> propertyFunc, TResult newValue) | |
{ | |
MemberInfo memberInfo = (propertyFunc.Body as MemberExpression)?.Member; | |
Action undoFunc = CreateUndoFunc(obj, memberInfo, newValue); | |
return new Undo(undoFunc); | |
} | |
public Undo(Action undoFunc) | |
{ | |
_undoFunc = undoFunc; | |
} | |
public void Dispose() | |
{ | |
_undoFunc(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example: