【问题标题】:Builder with support for nested objects支持嵌套对象的生成器
【发布时间】:2019-10-02 12:27:58
【问题描述】:

我是 C# 和一般编程的新手,当我发现以下问题时,我试图找出如何实现一个可以支持嵌套对象的构建器: Builder pattern with nested objects

公认的解决方案有效,但我意识到我并不完全理解代码中发生了什么。

尤其是定义动作的部分:

public ReceiptBuilder WithItem(string text, Action<ReceiptItemBuilder> itemBuilder)
{
    var rib = new ReceiptItemBuilder(text);
    itemBuilder(rib);
    r.AddItem(rib.Build());
    return this;
}

如果有人能解释一下这次通话中发生的事情会很好吗?

itemBuilder(rib);

【问题讨论】:

  • itemBuilder 是一个Action 委托,它采用ReceiptItemBuilder,这意味着它可以像带有签名void itemBuilder(ReceiptItemBuilder x) 的方法一样被调用。委托基本上是在 C# 中传递函数的方式。
  • 还有:ActionFunc
  • @OlivierRogier 别忘了Predicate
  • 感谢您的回复。我肯定会研究这些教程。 @juharr 但是当您调用 itemBuilder 并将其传递给 ReceiptItemBuilder 时会发生什么

标签: c# delegates builder


【解决方案1】:

Action 是一种委托类型,而在 C# 中,委托类型(如 ActionFuncPredicate,或者直接使用 delegate)是作为参数传递方法的方式。可以通过itemBuilder(rib)直接调用委托类型,这会执行带有参数rib的Action(方法)itemBuilder

它的作用是这样的:

首先我们用 Action 参数声明方法

public ReceiptBuilder WithItem(string text, Action<ReceiptItemBuilder> itemBuilder)

Action&lt;ReceiptItemBuilder&gt; 将我们的参数限制为返回void 并采用ReceiptItemBuilder 类型参数的方法。

所以我们现在可以声明一个符合这些条件的方法。这是我的:

public void ItemWithIngredient(ReceiptItemBuilder itemBuilder)
{
    itemBuilder.WithIngredients("Ingredients1");
}

然后像这样传递给WithItem

WithItem("Item1", ItemWithIngredient);

现在这没什么用,因为我们无法更改成分,因为我们是硬编码的。因此,我们使用一种称为匿名方法的方法,并使用 lambda 表达式来定义它,如下所示:

WithItem("Item1", i => i.WithIngredients("Ingredients1"));

i =&gt; ... 部分基本上声明了一个方法并使用它。 i 这里是参数,类型为ReceiptItemBuilder

这个答案有点杂乱无章,我不擅长解释事情。我强烈建议您查看 Olivier Rogier 在 cmets 中发布的链接,但这里是对三种标准委托类型的快速概述:

操作:Action 是一个返回 void 且不带参数的方法。它有一些像Action&lt;T&gt; 这样的重载,它表示一个方法,其参数类型为T(将T 替换为您想要的任何类型)。更多参数有更多重载(Action&lt;T1, T2&gt;Action&lt;T1, T2, T3&gt; ...)

Func:Func&lt;T&gt; 是一个返回 T 并且不带参数的方法(没有 Func,因为 Func 总是返回一些东西)。这也有重载,这些接受参数(Func&lt;TInput, TOutput&gt;Func&lt;TInput1, TInput2, TOutput&gt; ...)

谓词:Predicate&lt;T&gt; 始终采用一个参数并返回 bool

【讨论】:

  • 感谢您花时间尝试解释这个概念。你声称不擅长解释事情,但你的解释与其他以前的 cmets 一起帮助我更清楚了这一点。我意识到我还有很长的路要走,但至少现在我还没有完全迷失。
猜你喜欢
  • 2010-10-18
  • 2017-09-22
  • 2017-08-07
  • 2018-08-16
  • 1970-01-01
  • 2017-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多