【问题标题】:Update ref parameter inside anonymous method更新匿名方法中的 ref 参数
【发布时间】:2014-07-01 02:21:49
【问题描述】:

是否有解决方法来更新匿名方法中的 ref 参数?

我知道匿名方法不允许访问外部作用域的 ref 参数,但是还有其他方法吗?我正在为 MessageStream 使用外部库,因此无法更改委托的参数...

void DoWork(ref int count)
{
    MessageStream Stream = new MessageStream();
    Stream.MessageReceived += (o, args) =>
    {
        //Error cannot use ref or out parameter inside anonymous method
        count++;
    };
}

【问题讨论】:

  • 答案取决于您是否可以确定Stream.MessageReceived 将在DoWork 返回之前引发。你能确定吗?
  • 你知道不安全的上下文吗?如果没有,我会用这个解决方案发布答案​​
  • @faby 我想我知道你在想什么,如果我是对的,那是行不通的。它通常会工作,但有时会失败,并且无法修复它以使其始终工作。
  • 为什么你在那个参数上有ref?你确定你需要它吗?很少看到它被使用。如果您能向我们展示如何使用它的更多信息,我们或许可以建议另一种可行的方法。
  • @hvd 我知道这是不安全上下文的问题

标签: c# ref anonymous-methods


【解决方案1】:

在您的情况下,这个问题没有可行的解决方法:当Stream.MessageReceived 事件触发时,count 可能已经超出了您的DoWork 函数的调用者的范围。

在这种情况下,您应该将count 封装在一个对象中,并在事件处理程序和调用者中保留对该对象的引用,如下所示:

class Counter {
    public int Value {get;private set;}
    public void Increment() {Value++;}
}
void DoWork(Counter count) {
    MessageStream Stream = new MessageStream();
    Stream.MessageReceived += (o, args) => {
        count.Increment();
    };
}

【讨论】:

  • 可能互锁。增量在这里可能是明智的,具体取决于使用情况。
  • 我认为这是我实现它的唯一方法。一些代码按顺序重新调整。我希望它会以某种方式表现得很好。
【解决方案2】:

如果您想让委托从外部范围更新变量,请传递一个设置值的 lambda,而不是通过 ref 传递计数。

//shared var
private static int _count = 0;

//call your method
DoWork(() => _count++);  //instead of DoWork(ref _count);


void DoWork(Action countInc)
{
    MessageStream Stream = new MessageStream();
    Stream.Activated += (o, args) => countInc();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 2015-09-18
    相关资源
    最近更新 更多