我们有1个活动,2个订阅者。当事件上升第1个(功能)更改参数时,该参数为参考类型。第二个订户是否会更改参数或原点?
答案 0 :(得分:10)
您不能将参数更改为具有不同的值,假设它是一个按值参数,但是(一如既往)您可以修改该值所引用的对象。
示例:
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
换句话说:
StringBuilder
对象这与通过值传递参数的常规方法调用完全相同。
现在你可以声明委托使用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
...这表明sb
中action1
的价值变化在其他任何地方都可见。