2014-05-13 26 views
8

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

我知道一个匿名方法不允许访问外部范围的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++; 
    }; 
} 
+0

答案取决于你是否可以确定'Stream.MessageReceived'会在'DoWork'返回之前引发。你能确定吗? – hvd

+0

你知道不安全的上下文吗?如果没有我发布这个解决方案的答案 – faby

+0

@faby我想我知道你在想什么,如果我是对的,那是行不通的。它通常会*工作,但有时会失败,并且无法修复它,以便始终有效。 – hvd

回答

5

在你的情况下,有没有可行的变通方法,这一问题:由当时的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(); 
    }; 
} 
+0

可能Interlocked.Increment这里可能是明智的,这取决于使用情况。 – Paddy

+0

我认为这是我能够实现的唯一途径。一些代码按顺序重新调整。我希望它能以某种方式发挥出色。 – jamos

1

如果你想拥有委托更新来自外部作用域的变量,传递一个设置值的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(); 
}