我有这个代码:
public void AddMenuRow(FuncInvoker i_FuncToAdd) // add a row to menu.
{
if (d_Lines == null)
{
d_Lines = new FuncInvoker(i_FuncToAdd);
}
else
{
d_Lines += i_FuncToAdd;
}
}
Run Code Online (Sandbox Code Playgroud)
用于向调用列表添加方法.
现在我想将每个方法的名称打印到控制台,所以我做了这个:
public void Show()
{
int count = 1;
string name = null;
Console.WriteLine(m_Title);
foreach (FuncInvoker list in d_Lines.GetInvocationList())
{
name = list.Method.Name;
Console.WriteLine((count++) + ". " + name);
}
}
Run Code Online (Sandbox Code Playgroud)
问题在于第一个方法名称,由于某种原因总是打印"调用".委托链接中的下一个方法工作正常.
有人可以帮我弄这个吗?我尝试了一切.
在这一行:
d_Lines = new FuncInvoker(i_FuncToAdd);
Run Code Online (Sandbox Code Playgroud)
...您实际上正在创建一个包装原始委托的新委托实例.这个新委托的方法目标将是Invoke原始委托的方法(假设它是单播),这解释了你正在观察的行为.
显而易见的解决方法是不使用包装器,只是将对原始委托的引用复制到变量:
d_Lines = i_FuncToAdd;
Run Code Online (Sandbox Code Playgroud)
但你可以完全取消你的'特殊情况'分支并且只是做(假设参数不可能null):
public void AddMenuRow(FuncInvoker i_FuncToAdd)
{
d_Lines += i_FuncToAdd;
}
Run Code Online (Sandbox Code Playgroud)
这样可以正常工作Delegate.Combine(因为+=语法变为),如果第一个委托是null,则返回对第二个委托的引用,而不是抛出异常.