Igo*_*gor 7 c# delegates action reference ref
I'm passing a System.Action as a parameter to a method which does some lengthy operation and want to add more stuff to the invocation list after the Action has been passed:
class Class1
{
private System.Action onDoneCallback;
void StartAsyncOperation(System.Action onDoneCallback)
{
this.onDoneCallback = onDoneCallback;
// do lengthy stuff
}
void MuchLater()
{
this.onDoneCallBack?.Invoke();
}
}
class Class2
{
public System.Action action;
void DoStuff()
{
action += () => print ("a");
new Class1().StartAsyncOperation(action);
}
{
// ... much later in another place but still before StartAsyncOperation ends
action += () => print ("b");
}
}
Run Code Online (Sandbox Code Playgroud)
However, only the the stuff that was added with += before passing the Action as parameter is invoked. So, in this example, it will only print "a" but not "b".
This makes me think that System.Action is copied when it's passed as parameter (like a primitive type e.g. int would). So, when += is done later, it has no effect on the local copy of action inside SomeAsyncOperation.
I thought of passing System.Action with ref. However, I need to store it as member variable inside Class1, and I can't make a member variable a ref!
So, basically, the question is: how do you add more stuff to the invocation list of a callback after that callback has been passed and the lengthy operation is long on its way but hasn't ended yet.
EDIT:
Ended up replacing
new Class1().StartAsyncOperation(action);
Run Code Online (Sandbox Code Playgroud)
with
new Class1().StartAsyncOperation(() => action?.Invoke());
Run Code Online (Sandbox Code Playgroud)
委托类型是不可变的引用类型,如字符串:
s += "\n";
Run Code Online (Sandbox Code Playgroud)
s现在是对不同对象的引用。如果将其传递给方法,该方法将获取对此对象的引用,而不是s下一个可能引用的任何对象。该 lambda 返回并将继续返回,无论s调用 lambda 时所引用的对象是什么:
() => s;
Run Code Online (Sandbox Code Playgroud)
这同样适用于a += () => {};:a之后引用不同的对象,但您可以创建一个 lambda 来执行 的当前值a,无论它是什么。
因此:
new Class1().StartAsyncOperation(() => action());
Run Code Online (Sandbox Code Playgroud)
无论您在该点之后做什么action,您传入的 lambda 都会引用 的当前值action。
在家尝试一下:
Action a = () => Console.Write("a");
// This would print "a" when we call b() at the end
//Action b = a;
// This prints "a+" when we call b() at the end.
Action b = () => a();
a += () => Console.Write("+");
b();
Run Code Online (Sandbox Code Playgroud)