I am trying to support undo/redo for my application.
Then, I make it likes that, but I am not sure it is good practice.
interface ICommand
{
string Description{get;}
void Execute();
void Undo();
}
class Command<T> : ICommand
{
string m_actionDesc = string.empty;
T m_target;
Action<T> m_execute;
Action<T> m_undo;
public Command(T target, Action<T> execute, Action<T> undo)
{
m_target = target;
m_execute = execute;
m_undo = undo;
}
public string ActionDesc
{
get { return m_actionDesc; }
set { m_actionDesc = value; }
}
#region ICommand members
public string Description
{
get { return m_actionDesc; }
}
public void Execute()
{
m_execute(m_target);
}
public void Undo()
{
m_undo(m_target);
}
#endregion
}
Then, use them like that:
class LayerAction
{
//contains List<Layer>, Layer with string Name{get;set;}
LayerCollection m_layerCollection = new LayerCollection();
//contains LinkedList<ICommand>, and with public Add(ICommand) method to add cmd to list
CommandHistory m_history = new CommandHistory();
public void ReName(int index, string name)
{
string oldname = m_layerCollection[index].Name;
var cmd = new Command<DataLayer>(
m_layerCollection[index],
layer => layer.Name = name,
layer => layer.Name = oldname)
{
ActionDesc = "Rename"
};
m_history.AddCommand(cmd);
cmd.Execute();
}
}
I have tested it, and it worked well. but, I'm confused that:
-
the
lambda
can always work as my expected that auto generate class by C#closure effect
? If there are some traps, I need to pay attention to it? -
the
m_target
argument can reduce the numbers of compiler generate class which no need to capture local variable?
========== if not use closure, i have to write many boring classes like that:
class LayerReNameCommand : ICommand
{
Layer m_targetLayer;
string m_oldname;
string m_newname;
}
Aucun commentaire:
Enregistrer un commentaire