c# - 为什么这个 lambda 表达式对构造函数参数有效

标签 c# .net-6.0

我有一个 RelayCommand 的构造函数设置为:

public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)

在另一个脚本中我有:

    private Server _server;
    public RelayCommand ConnectToServerCommand {get; set;}

    public MainViewModel() // constructor
    {
        _server = new Server();


        //this syntax is confusing to me - not sure what it's doing
        ConnectToServerCommand = new(o => _server.Connect());
    }

我真的不明白 ConnectToServerCommand 的语法在MainViewModel构造函数。

RelayCommand接收具有对象参数类型的 Action,但 _server.Connect()方法有这个签名:

// Server
public void Connect()

为什么在没有对象作为参数之一时允许使用此方法?鉴于操作设置为 Action<object> .它如何认为这是一个有效的方法签名?

我对此还是个新手 - 所以我认为 lambda 表达式让我有些困惑,但不确定它们在这里是如何连接在一起的。

最佳答案

这个方法

o => _server.Connect()

与此方法相同

void Anon(object o) 
{
    // argument o is ignored
    _server.Connect();
}

使这段代码等同于你的:

private Server _server;
public RelayCommand ConnectToServerCommand {get; set;}

// un-lambda-ed
void Anon(object o) 
{
    _server.Connect();
}

public MainViewModel() // constructor
{
    _server = new Server();

    // no confusion
    ConnectToServerCommand = new(Anon);
}

让我们在构造函数中调用这两个函数:

public MainViewModel() // constructor
{
    _server = new Server();

    ConnectToServerCommand = new(o => _server.Connect());
    // no confusion
    ConnectToServerCommand = new(Anon);
}

然后比较生成的中间语言:


MainViewModel:
IL_0000:  ldarg.0     
IL_0001:  newobj      UserQuery+Server..ctor
IL_0006:  stfld       UserQuery._server              // _server = new Server();
IL_000B:  ldarg.0     
IL_000C:  ldarg.0     
IL_000D:  ldftn       UserQuery.<MainViewModel>b__0  // our lamda function, see below
IL_0013:  newobj      System.Action<System.Object>..ctor
IL_0018:  newobj      UserQuery+RelayCommand..ctor
IL_001D:  call        UserQuery.set_ConnectToServerCommand
IL_0022:  ldarg.0     
IL_0023:  ldarg.0     
IL_0024:  ldftn       UserQuery.Anon                 // our Anon call
IL_002A:  newobj      System.Action<System.Object>..ctor
IL_002F:  newobj      UserQuery+RelayCommand..ctor
IL_0034:  call        UserQuery.set_ConnectToServerCommand
IL_0039:  ret         

<MainViewModel>b__0:  // generated by the compiler for us, the lambda
IL_0000:  ldarg.0     // object o, nothing gets done with that
IL_0001:  ldfld       UserQuery._server
IL_0006:  callvirt    UserQuery+Server.Connect
IL_000B:  ret         

Anon:
IL_0000:  ldarg.0     // object o, nothing gets done with that
IL_0001:  ldfld       UserQuery._server
IL_0006:  callvirt    UserQuery+Server.Connect
IL_000B:  ret         

那是惊人的相似。

关于c# - 为什么这个 lambda 表达式对构造函数参数有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73760622/

相关文章:

c# - 如何将数组(在 VB6 中通过引用)传递给 C\C++ *.dll 子例程?

c# - OpenFileDialog 文件名为 UTF8

c# - WPF C# 如何为 HighlightBrush 颜色设置动画?

azure - .net 6.0 与 nuget 包的兼容性问题

c# - 为什么 GetShortestDayName 返回的名称比预期的要短?

c# - Automapper - 集合 <double> 中的 map 设置失败

c# - 线程安全代码变得过于笨拙?

c# - Xamarin.forms-如何在 View 模型内的条目中检测回车?

c# - System.Text.Json - 将第三方枚举数组序列化为字符串数组

entity-framework - EF Core 以升级后可以翻译的形式重写查询