Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用参数从lambda表达式创建委托?_C#_Reflection_Delegates_Lambda_Relaycommand - Fatal编程技术网

C# 如何使用参数从lambda表达式创建委托?

C# 如何使用参数从lambda表达式创建委托?,c#,reflection,delegates,lambda,relaycommand,C#,Reflection,Delegates,Lambda,Relaycommand,我正在尝试使用参数动态创建RelayCommand的实例: public class RelayCommand<T> : ICommand { #region Declarations private readonly Predicate<T> _canExecute; private readonly Action<T> _execute; #endregion #region Constructors

我正在尝试使用参数动态创建RelayCommand的实例:

public class RelayCommand<T> : ICommand
{
    #region Declarations

    private readonly Predicate<T> _canExecute;
    private readonly Action<T> _execute;

    #endregion

    #region Constructors

    /// <summary>
    /// Initializes a new instance of the <see cref="RelayCommand&lt;T&gt;"/> class and the command can always be executed.
    /// </summary>
    /// <param name="execute">The execution logic.</param>
    public RelayCommand(Action<T> execute)
        : this(execute, null)
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="RelayCommand&lt;T&gt;"/> class.
    /// </summary>
    /// <param name="execute">The execution logic.</param>
    /// <param name="canExecute">The execution status logic.</param>
    public RelayCommand(Action<T> execute, Predicate<T> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");
        _execute = execute;
        _canExecute = canExecute;
    }
我想动态地将它们挂接到RelayCommand的一个实例,如下所示:

ICommand command = new RelayCommand<ViewModel>((x)=>myviewmodel.MyMethod(myparameter),(x)=> myviewmodel.CanExecuteMyMethod(myparameter));
ICommand命令=newrelaycommand((x)=>myviewmodel.MyMethod(myparameter),(x)=>myviewmodel.CanExecuteMyMethod(myparameter));
但是,前一行是有效的,我的方法名是在运行时传入的,因此我需要动态地实现相同的功能

编辑:只是一些澄清:在我的场景中,我不能直接按名称引用我的方法。我将用于创建RelayCommand的方法名将作为字符串传递

解决方案:

这是我的最终解决方案,使用@ZafarYousafi建议。请注意,我是如何为我的RelayCommand以及Action和Predicate使用通用“object”类型的,因为这是我的方法参数(object myparameter)的类型:

object myparameter=//在这里分配一些值。
委托td1=null,td2=null;
MethodInfo method1=myviewmodel.GetType().GetMethod(“MyMethodNameAsString”);
if(tmethod1!=null)
td1=Delegate.CreateDelegate(typeof(Action),myviewmodel,method1);
MethodInfo tmethod=viewmodel.GetType().GetMethod(“Can”+“MyMethodNameAsString”);
if(method2!=null)
d2=Delegate.CreateDelegate(typeof(谓词),myviewmodel,method2);
如果(d1!=null&&d2!=null)
{
item.Command=newrelaycommand(obj=>((Action)td1)(myparameter),obj=>((谓词)td2)(myparameter));
}
这应等同于:

item.Command = new RelayCommand<object>(param=>myviewmodel.MyMethod(myparameter),param=>myviewmodel.CanMyMethod(myparameter));
item.Command=newrelaycommand(param=>myviewmodel.MyMethod(myparameter),param=>myviewmodel.CanMyMethod(myparameter));
重要提示:正如@DanC所指出的,Josh Smith创建的RelayCommand类在创建时不打算接收参数。在架构良好的MVVM解决方案中,RelayCommand参数将通过CommandParameter属性的XAML绑定传递。因此,如果您有一个button.Command绑定到RelayCommand,您还需要绑定button.CommandParameter,如前所述

以前失败的尝试: 这就是我到目前为止所做的:

                Delegate d1 = null, d2 = null;
                MethodInfo method1 = myviewmodel.GetType().GetMethod("MyMethodNameAsString");
                if (method1 != null)
                    d1 = Delegate.CreateDelegate(typeof(Action<ViewModel>), myviewmodel, method1);

                MethodInfo method2 = myviewmodel.GetType().GetMethod("Can" + "MyMethodNameAsString");
                if (method2 != null)
                    d2 = Delegate.CreateDelegate(typeof(Predicate<ViewModel>), myviewmodel, method2);

                if (d1 != null && d2 != null)
                {
                    item.Command = new RelayCommand<ViewModel>((Action<ViewModel>)d1, (Predicate<ViewModel>)d2);
                }
委托d1=null,d2=null;
MethodInfo method1=myviewmodel.GetType().GetMethod(“MyMethodNameAsString”);
if(method1!=null)
d1=Delegate.CreateDelegate(typeof(Action),myviewmodel,method1);
MethodInfo method2=myviewmodel.GetType().GetMethod(“Can”+“MyMethodNameAsString”);
if(method2!=null)
d2=Delegate.CreateDelegate(typeof(谓词),myviewmodel,method2);
如果(d1!=null&&d2!=null)
{
item.Command=newrelaycommand((动作)d1,(谓词)d2);
}
运行良好,没有编译或运行时错误,但我不知道如何运行 通过relaycom和构造函数参数传递我的参数

任何建议都将不胜感激

谢谢


与my

相关,只需在RelayCommand类上定义一个方法来执行如下命令:

public void Execute(T model)
    {
        if(_canExecute(model))
            _execute(model);
    }

只需在RelayCommand类上定义一个方法来执行如下命令:

public void Execute(T model)
    {
        if(_canExecute(model))
            _execute(model);
    }

根据Josh Smith在网站上发布的代码。您可以使用lambda变量param来传递参数。在您的示例中,根本没有使用“x”lambda变量。这个变量应该是Execute和CanExecute方法的参数

RelayCommand _saveCommand;
public ICommand SaveCommand
{
    get
    {
        if (_saveCommand == null)
        {
            _saveCommand = new RelayCommand(param => this.Save(),
                param => this.CanSave );
        }
        return _saveCommand;
    }
}
假设该命令是在ViewModel中创建的,那么您可以按如下方式初始化它

ICommand command = new RelayCommand<MyParameterType>((myparameter)=>this.MyMethod(myparameter),(myparameter)=> this.CanExecuteMyMethod(myparameter));
Delegate d1 = null, d2 = null;
            MethodInfo method1 = myviewmodel.GetType().GetMethod("MyMethodNameAsString");
            if (method1 != null)
                d1 = Delegate.CreateDelegate(typeof(Action<YourParameterType>), myviewmodel, method1);

            MethodInfo method2 = myviewmodel.GetType().GetMethod("Can" + "MyMethodNameAsString");
            if (method2 != null)
                d2 = Delegate.CreateDelegate(typeof(Predicate<YourParameterType>), myviewmodel, method2);

            if (d1 != null && d2 != null)
            {
                item.Command = new RelayCommand<YourParameterType>((Action<YourParameterType>)d1, (Predicate<YourParameterType>)d2);
            }
ICommand命令=newrelaycommand((myparameter)=>this.MyMethod(myparameter),(myparameter)=>this.CanExecuteMyMethod(myparameter));
由于您不能使用lamba来构造命令,因此您的代码如下所示

ICommand command = new RelayCommand<MyParameterType>((myparameter)=>this.MyMethod(myparameter),(myparameter)=> this.CanExecuteMyMethod(myparameter));
Delegate d1 = null, d2 = null;
            MethodInfo method1 = myviewmodel.GetType().GetMethod("MyMethodNameAsString");
            if (method1 != null)
                d1 = Delegate.CreateDelegate(typeof(Action<YourParameterType>), myviewmodel, method1);

            MethodInfo method2 = myviewmodel.GetType().GetMethod("Can" + "MyMethodNameAsString");
            if (method2 != null)
                d2 = Delegate.CreateDelegate(typeof(Predicate<YourParameterType>), myviewmodel, method2);

            if (d1 != null && d2 != null)
            {
                item.Command = new RelayCommand<YourParameterType>((Action<YourParameterType>)d1, (Predicate<YourParameterType>)d2);
            }
委托d1=null,d2=null;
MethodInfo method1=myviewmodel.GetType().GetMethod(“MyMethodNameAsString”);
if(method1!=null)
d1=Delegate.CreateDelegate(typeof(Action),myviewmodel,method1);
MethodInfo method2=myviewmodel.GetType().GetMethod(“Can”+“MyMethodNameAsString”);
if(method2!=null)
d2=Delegate.CreateDelegate(typeof(谓词),myviewmodel,method2);
如果(d1!=null&&d2!=null)
{
item.Command=newrelaycommand((动作)d1,(谓词)d2);
}

现在,在将命令分配给MenuItem对象(在本例中为ICommandSource)后,它将使用CommandParameter调用您的两个委托(d1、d2)。

根据Josh Smith在中发布的代码。您可以使用lambda变量param来传递参数。在您的示例中,根本没有使用“x”lambda变量。这个变量应该是Execute和CanExecute方法的参数

RelayCommand _saveCommand;
public ICommand SaveCommand
{
    get
    {
        if (_saveCommand == null)
        {
            _saveCommand = new RelayCommand(param => this.Save(),
                param => this.CanSave );
        }
        return _saveCommand;
    }
}
假设该命令是在ViewModel中创建的,那么您可以按如下方式初始化它

ICommand command = new RelayCommand<MyParameterType>((myparameter)=>this.MyMethod(myparameter),(myparameter)=> this.CanExecuteMyMethod(myparameter));
Delegate d1 = null, d2 = null;
            MethodInfo method1 = myviewmodel.GetType().GetMethod("MyMethodNameAsString");
            if (method1 != null)
                d1 = Delegate.CreateDelegate(typeof(Action<YourParameterType>), myviewmodel, method1);

            MethodInfo method2 = myviewmodel.GetType().GetMethod("Can" + "MyMethodNameAsString");
            if (method2 != null)
                d2 = Delegate.CreateDelegate(typeof(Predicate<YourParameterType>), myviewmodel, method2);

            if (d1 != null && d2 != null)
            {
                item.Command = new RelayCommand<YourParameterType>((Action<YourParameterType>)d1, (Predicate<YourParameterType>)d2);
            }
ICommand命令=newrelaycommand((myparameter)=>this.MyMethod(myparameter),(myparameter)=>this.CanExecuteMyMethod(myparameter));
由于您不能使用lamba来构造命令,因此您的代码如下所示

ICommand command = new RelayCommand<MyParameterType>((myparameter)=>this.MyMethod(myparameter),(myparameter)=> this.CanExecuteMyMethod(myparameter));
Delegate d1 = null, d2 = null;
            MethodInfo method1 = myviewmodel.GetType().GetMethod("MyMethodNameAsString");
            if (method1 != null)
                d1 = Delegate.CreateDelegate(typeof(Action<YourParameterType>), myviewmodel, method1);

            MethodInfo method2 = myviewmodel.GetType().GetMethod("Can" + "MyMethodNameAsString");
            if (method2 != null)
                d2 = Delegate.CreateDelegate(typeof(Predicate<YourParameterType>), myviewmodel, method2);

            if (d1 != null && d2 != null)
            {
                item.Command = new RelayCommand<YourParameterType>((Action<YourParameterType>)d1, (Predicate<YourParameterType>)d2);
            }
委托d1=null,d2=null;
MethodInfo method1=myviewmodel.GetType().GetMethod(“MyMethodNameAsString”);
if(method1!=null)
d1=Delegate.CreateDelegate(typeof(Action),myviewmodel,method1);
MethodInfo method2=myviewmodel.GetType().GetMethod(“Can”+“MyMethodNameAsString”);
if(method2!=null)
d2=Delegate.CreateDelegate(typeof(谓词),myviewmodel,method2);
如果(d1!=null&&