对作为参数传递的 C# 委托(delegate)感到困惑:
class Program
{
static void Main(string[] args)
{
var a = new A();
Action holder = delegate{};
//a.Attach1(holder); //nothing printed
a.Attach2(ref holder);//print as expected
holder();
}
}
public class A
{
private void P1()
{
Console.WriteLine("Inaccessible");
}
public void P2()
{
Console.WriteLine("Accessible");
}
public void Attach1(Action holder)
{
holder += P1;
holder += P2;
}
public void Attach2(ref Action holder)
{
holder += P1;
holder += P2;
}
}
delegate 是引用类型,为什么还需要像 Attach2 中那样用字体中的 ref 传递才能正常工作,类似于值类型?
从 C++ 的经验来看,委托(delegate)只是一个函数指针,Attach1(Action holder) 类似于 Attach1(Action* holder),原始持有者作为“值”传递,因此未分配,而在第二种情况下,Attach2 (ref Action holder) 类似于 Attach1(Action** holder),实际传递的是指针,因此可以正确操作。但是为什么在 .NET 中没有指示或提示???
最佳答案
因为委托(delegate)实例是不可变,而+=
是对新委托(delegate)实例的新赋值;它基本上是:
holder = (Action)Delegate.Combine(holder, P1);
holder = (Action)Delegate.Combine(holder, P2);
如果您不将其作为 ref
传递,则在方法之外将看不到新值。
或者用更简单的术语来说——考虑一个string
; string
同样是不可变的,+=
是一个赋值。现在考虑:
public void Append(string s) {
s += "[suffix]";
}
public void Append2(ref string s) {
s += "[suffix]";
}
如果我们调用:
string x = "abc";
Append(x);
Console.WriteLine(x);
我们将看到abc
。如果我们调用
string x = "abc";
Append2(ref x);
Console.WriteLine(x);
我们将看到 abc[suffix]
- 出于完全相同的原因。
关于c# - .NET Delegate 作为参数传递问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16957796/