【问题标题】:c# how to modify parameter that is passing through a delegatec#如何修改通过委托传递的参数
【发布时间】:2018-03-26 22:11:41
【问题描述】:

我有以下代表

System.Action<SomeMessage> TheDelegate;

其中有几个订阅者,但是当消息通过所有订阅者时,每个订阅者都会对其执行某些操作,并且该更改会持续存在并传递给下一个订阅者,这是我不想要的。

有没有办法可以将原始消息用作所有订阅者的参数?

编辑: SomeMessage 是一个类,因此它通过订阅者通过引用传递

【问题讨论】:

  • 什么是SomeMessage?是结构体吗?
  • 它是一个类,所以参数作为引用传递
  • 由于类是通过引用传递的,因此您只需要一条原始消息。我认为这已经是您描述的必需行为。
  • 对不起,我的表情真的很糟糕。所以我想使用原始消息,但我不希望订阅者引起的任何更改持续存在。

标签: c# delegates pass-by-reference


【解决方案1】:

列举两种可能性:

  • 每次将消息传递给订阅者时克隆消息。消息的结构如何,克隆是否便宜?也许您甚至可以将其传递为struct?可以通过实现ICloneable 来完成克隆,基于每个属性进行克隆,这可以通过框架自动化,例如 Automapper (http://automapper.org),或者,如果您使用 JSON.NET 之类的 JSON Lib,您可以做类似var clone = FromJson(ToJson(original)) 的事情。这肯定不是一种快速的方法,而是一种适用于深层对象的简单方法。

  • 另一种方法是使消息本身不可变,并让每个订阅者将更改请求传递给某种收集器,例如

像这样:

interface ICommandSequence
{
    void AddCommand(ICommand);
}

动作变成了

System.Action<ImmutableMessage, ICommandSequence>

现在每个订阅者都可以将命令实例传递给ICommandSequence 实例。在调用了所有订阅者之后,您可以执行命令序列,并将更改应用于消息对象。命令的外观取决于您的消息和消息处理的外观。

如果您的应用程序关心一个高度关注业务领域的设计,您可以构建代表现实世界业务事件的命令,例如在 CQRS 中所做的那样。

【讨论】:

  • 您能否详细说明第一种可能性?我正在考虑这个问题,但找不到这样做的方法。如果我执行TheDelegate(message.Clone()) 之类的操作,则会发生同样的事情,因为对克隆的更改也会持续存在。
  • OK 您的消息对象看起来如何?是平的吗?属性是原始类型吗?有什么花哨的东西会使克隆变得困难吗?您必须每次为每个订阅者克隆消息,然后肯定会隔离更改。
  • 我添加了一些关于克隆实现的信息
猜你喜欢
  • 1970-01-01
  • 2020-07-28
  • 2012-07-12
  • 1970-01-01
  • 2011-05-29
  • 2015-08-11
  • 1970-01-01
  • 1970-01-01
  • 2016-09-03
相关资源
最近更新 更多