Click here to Skip to main content
15,889,856 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Okay, I have to put up my hands and admit I am guilty of copying code (in a hurry) without understanding it.

The code I copied was for an implementation of the System.Windows.Input.ICommand interface. I can't find the source of the code I copied, but reviewing it now, I've decided it looks odd to me.

Here is the code that concerns me.

public class Command : ICommand
{
    public Command( Action<object> execute )
    {
        _execute = execute;
    }

	public Command( Action execute ) : this( (Action<object>)( o => execute() ) )
	{
	}

	private readonly Action<object> _execute = null;
}


It appears to be doing constructor chaining in order to store a parameter of type Action in a variable of type Action<object>. It compiles and the following tests seem to indicate it is working fine:

[TestClass]
public class UTSupportCommand
{
    [TestMethod]
    public void Command_with_Action_parameter_executes()
    {
        Command command = new Command( ActionWithObjectParameter );
        command.Execute( "A" );
        Assert.IsTrue( _t1 == "A" );
    }

    [TestMethod]
    public void Command_with_no_parameter_executes()
    {
        Command command = new Command( ActionWithNoParameter );
        command.Execute( "X" );
        Assert.IsTrue( _t2 == "B" );
    }

    private void ActionWithObjectParameter( object s )
    {
        _t1 = (string)s;
    }

    private void ActionWithNoParameter()
    {
        _t2 = "B";
    }

    private string _t1 = "Z";
    private string _t2 = "Z";
}


What really puzzles me is how I can pass a parameter into the Action that takes no parameter. What happens to it?

I'd appreciate any comments on whether there is anything wrong with this code and what exactly it is doing.

Kind wishes ~ Patrick

What I have tried:

I have tried the tests shown above, which seem to run fine.
Posted
Updated 2-Aug-18 7:45am

1 solution

This is just fine, because you are in fact wrapping the non-generic Action (takes no parameters) with Action<t>.

Think about it this way: when you pass an argument to a method, is there a requirement that parameter be used? Consider:

C#
public bool DoSomething(int useless)
{
   return true;
}


Now, the Command constructor works as you implied: if it gets a non-generic Action it will wrap it in Action<object>. The wrapped command does nothing with the object argument, just like the example above does nothing with it, but it will now execute and match the expected signature.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900