可以委托代理链中的更改参数吗? (C#)

问题描述:

我们有1个事件,2个订户。当事件发生时第一个子函数(函数)改变参数,这个参数是参考类型。第二位订户是否会更改参数或原始参数?可以委托代理链中的更改参数吗? (C#)

+1

你可以添加一个代码示例来显示你的意思吗?我怀疑你所说的答案是他们得到了改变的参数,但代码示例会使问题更清楚。 –

+1

请注意,这里没有任何特定的事件 - 最好是仅以代表的方式说出您的问题,并尽可能简化。 –

您不能将该参数更改为具有不同的值(假设它是按值参数),但是(一如既往)您可能能够修改该值所引用的对象。

实施例:

using System; 
using System.Text; 

class Test 
{ 
    static void Main(string[] args) 
    { 
     Action<StringBuilder> action1 = sb => 
     { 
      Console.WriteLine(sb); 
      sb = new StringBuilder("x"); 
     }; 
     Action<StringBuilder> action2 = sb => 
     { 
      Console.WriteLine(sb); 
      sb.Append("y"); 
     }; 
     Action<StringBuilder> action3 = sb => 
     { 
      Console.WriteLine(sb); 
      sb.Append("z"); 
     }; 

     Action<StringBuilder> all = action1 + action2 + action3; 
     StringBuilder builder = new StringBuilder("a"); 
     all(builder); 
     Console.WriteLine(builder); 
    } 
} 

输出:

a 
a 
ay 
ayz 

换句话说:

  • 第一作用改变其参数的值;这并不影响别的
  • 第二个动作追加“Y”的StringBuilder对象的参数是指
  • 第三个行动可以“看到”第二行动所做的更改,并将其追加“Z”
  • 代表们已经调用
  • 后,他们的变化是显而易见的给调用者

这一切都是完全一样的普通方法调用按值传递的参数。

现在你可以声明一个委托使用ref参数 - 此时它的行为像一个ref参数的方法,并更改参数本身到链后代表可见。下面是一个使用新RefAction<T>代表一个上面的例子中的版本:

using System; 
using System.Text; 

delegate void RefAction<T>(ref T arg); 

class Test 
{ 
    static void Main(string[] args) 
    { 
     RefAction<StringBuilder> action1 = (ref StringBuilder sb) => 
     { 
      Console.WriteLine(sb); 
      sb = new StringBuilder("x"); 
     }; 
     RefAction<StringBuilder> action2 = (ref StringBuilder sb) => 
     { 
      Console.WriteLine(sb); 
      sb.Append("y"); 
     }; 
     RefAction<StringBuilder> action3 = (ref StringBuilder sb) => 
     { 
      Console.WriteLine(sb); 
      sb.Append("z"); 
     }; 

     RefAction<StringBuilder> all = action1 + action2 + action3; 
     StringBuilder builder = new StringBuilder("a"); 
     all(ref builder); 
     Console.WriteLine(builder); 
    } 
} 

现在输出的是:

a 
x 
xy 
xyz 

...这表明在action1的变化的sb其他地方都可见。