If your Invoker needs to send arguments to command and you really want to do it in type-safe way(which is not usually so easy if we are dealing with composition if objects rather than inheritance), then I would parameterize Invoker with type of arguments-parameters that it can call, so that now Invoker may call commands that support such type of parameters. Sthm like that.
public abstract class Command<T> where T:class
{
public abstract void Execute(T par);
}
public class ConcreteCommand<T> : Command<T> where T : class
{
private readonly Receiver<T> _receiver;
public ConcreteCommand(Receiver<T> receiver)
{
_receiver = receiver;
}
#region Overrides of Command<T>
public override void Execute(T par)
{
_receiver.MenuItemClick(par);
}
#endregion
}
public class Invoker<T> where T : class
{
private readonly T par;
private readonly Command<T> cmd;
public Invoker(T par, Command<T> cmd)
{
this.par = par;
this.cmd = cmd;
}
public void Invoke()
{
cmd.Execute(par);
}
}
public class Receiver<T> where T : class
{
public void MenuItemClick(T e)
{
Console.WriteLine("Parameter types {0}", e.GetType().FullName);
}
}
static internal class CmdBuilder
{
public static Command<T> PrepareCommand<T>() where T : class
{
Receiver<T> rcv = new Receiver<T>();
Command<T> cmd = new ConcreteCommand<T>(rcv);
return cmd;
}
}
class Program
{
static void Main(string[] args)
{
var cmd = CmdBuilder.PrepareCommand<EventArgs>();
cmd.Execute(new EventArgs());
Console.ReadKey(true);
}
}
Other option is to use parameter-object. Since all commands "know" what type of parameters they are expecting they can cast it to specific realization of parameter-object. But that wouldn't give you compile errors