c# - 委托(delegate)可以更改委托(delegate)链中的参数吗? (C#)

标签 c# events

我们有 1 个事件,2 个订阅者。当事件发生时,第一个订阅者(函数)更改参数并且此参数是引用类型。第二个订阅者会得到更改的参数还是原始参数?

最佳答案

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

例子:

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

换句话说:

  • 第一个 Action 改变了它的参数值;这不会影响其他任何事情
  • 第二个操作将“y”附加到 StringBuilder其参数所指的对象
  • 第三个 Action 可以“看到”第二个 Action 所做的改变,它附加了“z”
  • 调用委托(delegate)后,调用者可以看到它们的更改

这与按值传递参数的常规方法调用完全相同。

现在您可以声明一个委托(delegate)来使用ref参数 - 此时它的行为类似于带有 ref 的方法参数,以及对参数本身的更改对链中的后续委托(delegate)可见。这是使用新的 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 在其他任何地方都可见。

关于c# - 委托(delegate)可以更改委托(delegate)链中的参数吗? (C#),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41415515/

相关文章:

nhibernate - 在更新 nhibernate 之前更改属性值

c# - 获取 VSTO 中先前标记的 Excel 单元格的范围

c# - 如何设置列表项值属性以更正数据库表行中的 ID?

javascript - 如何使用 onclick 事件触发此代码。我尝试过但失败了

Python多处理: How to shutdown a long running process that is a sequence of actions

javascript - IE 不在具有 ONE FIELD 的表单上触发键盘事件

html - 'Next' 的按键事件

c# - 运行任务,做某事然后等待?

c# - 冒泡要订阅的事件

具有标志属性的 C# 枚举