gpt4 book ai didi

C# - 匿名函数和事件处理程序

转载 作者:IT王子 更新时间:2023-10-29 04:29:06 25 4
gpt4 key购买 nike

我有以下代码:

public List<IWFResourceInstance> FindStepsByType(IWFResource res)  
{
List<IWFResourceInstance> retval = new List<IWFResourceInstance>();
this.FoundStep += delegate(object sender, WalkerStepEventArgs e)
{
if (e.Step.ResourceType == res) retval.Add(e.Step);
};
this.Start();
return retval;
}

请注意我是如何将我的事件成员 (FoundStep) 注册到本地就地匿名函数的。

我的问题是:“FindStepByType”函数何时结束——匿名函数会自动从事件的委托(delegate)列表中删除,还是我必须在退出该函数之前手动删除它? (我该怎么做?)

我希望我的问题很清楚。

最佳答案

您的代码有一些问题(您和其他人已经确定了一些问题):

  • 无法按照编码从事件中删除匿名委托(delegate)。
  • 匿名委托(delegate)的生命周期将比调用它的方法的生命周期长,因为您已将它添加到this 的成员FoundStep
  • 每次进入 FindStepsByType 都会向 FoundStep 添加另一个匿名委托(delegate)。
  • 匿名委托(delegate)是一个闭包,有效地延长了 retval 的生命周期,因此即使您停止在代码的其他地方引用 retval,它仍然由匿名委托(delegate)持有.

要解决这个问题,并且仍然使用匿名委托(delegate),将其分配给一个局部变量,然后删除 finally block 中的处理程序(在处理程序抛出异常的情况下是必需的):

  public List<IWFResourceInstance> FindStepsByType(IWFResource res)
{
List<IWFResourceInstance> retval = new List<IWFResourceInstance>();
EventHandler<WalkerStepEventArgs> handler = (sender, e) =>
{
if (e.Step.ResourceType == res) retval.Add(e.Step);
};

this.FoundStep += handler;

try
{
this.Start();
}
finally
{
this.FoundStep -= handler;
}

return retval;
}

在 C# 7.0+ 中,您可以将匿名委托(delegate)替换为本地函数,从而达到相同的效果:

    public List<IWFResourceInstance> FindStepsByType(IWFResource res)
{
var retval = new List<IWFResourceInstance>();

void Handler(object sender, WalkerStepEventArgs e)
{
if (e.Step.ResourceType == res) retval.Add(e.Step);
}

FoundStep += Handler;

try
{
this.Start();
}
finally
{
FoundStep -= Handler;
}

return retval;
}

关于C# - 匿名函数和事件处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1389543/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com