【问题标题】:Composing multicast delegates in C# - should I use operators or Action.Combine?在 C# 中编写多播委托 - 我应该使用运算符还是 Action.Combine?
【发布时间】:2013-01-07 14:24:46
【问题描述】:

阅读文档我可以看到+ 运算符可用于组合/组合相同类型的委托。

以同样的方式,我可以看到我可以使用 - 运算符从组合委托中删除 a。

我还注意到Action 类型具有静态CombineRemove 方法,可用于连接两个委托的调用列表,并从另一个委托的调用列表。

        Action a = () => Debug.WriteLine("Invoke a");
        Action b = () => Debug.WriteLine("Invoke b");
        a += b;
        a.Invoke(); 

        //Invoke a
        //Invoke b

        Action c = () => Debug.WriteLine("Invoke c");
        Action d = () => Debug.WriteLine("Invoke d");
        Action e = Action.Combine(c, d);
        e.Invoke();

        //Invoke c
        //Invoke d

        a -= b;
        a.Invoke();

        //Invoke a

        e = Action.Remove(e, d);
        e.Invoke(); 

        //Invoke c

就它们如何组合/从调用列表中删除而言,它们似乎产生了相同的结果。

我已经在 SO 和其他代码的各种示例中看到了这两种方法。有没有理由我应该使用一种或另一种方式?有坑跌吗?例如 - 我可以在 a -= b; 行中看到一条警告,指出 Delegate subtraction has unpredictable results - 那么我应该使用 Remove 来避免这种情况吗?

【问题讨论】:

  • Obviously the static methods return a new delegate whilst the accessors don't
  • “委托减法具有不可预测的结果”是 ReSharper 的警告,而且措辞似乎很糟糕。结果是完全可以预测的。它们在 C# 规范中定义。然而,对于一些用户来说,他们的委托减法心智模型不符合规范,因此结果对他们来说是“不可预测的”。
  • @SLaks - 你能进一步解释一下吗? a += b 不会返回新的 Delegate,而 Delegate.Combine(a, b) 显然会返回。
  • @mike z - 是的,这有点精神......哈......
  • @Fraser:错了。 a += ba = a + b 的简写(就像任何其他 += 添加一样),它显然确实返回了一个新的委托。 (注意事件是完全不同的)

标签: c# delegates accessor


【解决方案1】:

委托运算符(+-)是静态方法的简写。
完全没有区别。

a += b 编译为a = (Action)Delegate.Combine(a, b)

【讨论】:

  • 非常感谢 - 真正让我感到困惑的是 a += ba 保留为 Action 类型,而 Delegate.Combine(a, b) 返回 Delegate 类型而不是 Action 类型。 .
  • @Fraser:如果您查看生成的 IL,您会在 Delegate.Combine 之后看到 castclass 指令,用于 +=。 (你可以在 LINQPad 中看到)
  • ...所以 - 访问器不返回 Delegate 类型,它们返回与正在组合的两个对象(在本例中为 Action)相同类型的对象,而静态方法总是返回一个Delegate。我想我只是说“代表”而不是输入Delegate,从而混淆了这个问题
  • @Fraser:(请注意,它们被称为 operators,而不是 accessors)。操作符做的事情与方法完全相同;静态方法也返回与其操作数相同的类型。
  • 啊,是的……是我使用了Delegate.Combine……而不是Action.Combine。很抱歉造成混乱。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-11
  • 2012-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-07
  • 1970-01-01
相关资源
最近更新 更多