我有一个 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/