是否可以隐式将动作分配给void委托?

Tre*_*key 4 c# delegates types casting function

我有一个需要用void委托构造的类:

//an object that's constructed with a "void delegate of no params"
public class BindableCommand
{
    public delegate void ExecuteMethod();
    private readonly ExecuteMethod _executeMethod;

    public BindableCommand(ExecuteMethod executeMethod)
    {
        _executeMethod = executeMethod;
    }
}
Run Code Online (Sandbox Code Playgroud)

它的工作原理如下:

public class Test
{
    public static void Main()
    {
        //creates a bindable command
        BindableCommand b = Create();
    }

    private static BindableCommand Create(){
        BindableCommand b = new BindableCommand(Function);
        return b;
    }

    private static void Function(){}
}
Run Code Online (Sandbox Code Playgroud)

我现在想Function在构建前作为参数传递BindableCommand.
我的尝试无法编译:

public class Test
{
    public static void Main()
    {
        //creates a bindable command
        BindableCommand b = Create(Function);
    }

    private static BindableCommand Create(Action action){
        BindableCommand b = new BindableCommand(action);
        return b;
    }

    private static void Function(){}
}
Run Code Online (Sandbox Code Playgroud)
prog.cs(20,19): warning CS0219: The variable `b' is assigned but its value is never used
prog.cs(24,23): error CS1502: The best overloaded method match for `BindableCommand.BindableCommand(BindableCommand.ExecuteMethod)' has some invalid arguments
prog.cs(9,12): (Location of the symbol related to previous error)
prog.cs(24,43): error CS1503: Argument `#1' cannot convert `System.Action' expression to type `BindableCommand.ExecuteMethod'
Run Code Online (Sandbox Code Playgroud)

但我以为Action是一个void delegate()

我无法通过空委托:

private static BindableCommand Create(delegate void action){/* ... */}
Run Code Online (Sandbox Code Playgroud)

看来我必须做以下事情:

private static BindableCommand Create(BindableCommand.ExecuteMethod action){/* ... */}

有没有办法让演员自动出现?

Eri*_*ert 14

您希望C#拥有的功能称为"结构委托转换".也就是说,如果你有两个委托类型并且它们都接受一个int并返回一个字符串,那么你应该能够将一种类型的值分配给另一种类型.

C#没有此功能.包括我自己在内的许多人都对.NET 1.0中的代表没有引入结构化类型表示遗憾.那为什么不包括在内?

设计考虑因素是您可能希望在委托类型中编码语义信息:

delegate R Pure<A, R>(A a);
delegate R Impure<A, R>(A a);
Run Code Online (Sandbox Code Playgroud)

"纯"功能是一种没有副作用的功能,其输出由输入唯一确定.例如,您可能想说比较函数必须是纯粹的.如果输入没有改变,我们不希望比较改变它的值,我们不期望它产生副作用.

显然,能够将不纯的委托值分配给纯委托类型的变量是错误的.因此类型系统会阻止它,即使代表在结构上是相同的.

实际上,很少有人将这样的语义信息放在代表中.允许结构转换会更方便.

有一种方法可以在结构委托类型之间进行转换,但它不是很好:

Action a = whatever;
ExecuteMethod e = a.Invoke;
Run Code Online (Sandbox Code Playgroud)

也就是说,为其创建的委托e委托的invoke方法的委托a. 所以调用einvokes a,调用所需的方法.这是间接的额外步骤,但是人们希望性能损失不是太大.