如何使构建方法默认为在c#构建器流畅接口中调用

本文关键字:构建 接口 调用 方法 何使 默认 | 更新日期: 2023-09-27 18:16:27

我需要,使用一个像下一个代码的构建器…

var foo = FooBuilder
          .WithSomething()
          .WithOtherthing();

var foo = FooBuilder
          .WithOtherthing()
          .WithSomething();

的作用如下:

var foo = FooBuilder
          .WithSomething()
          .WithOtherthing()
          .Build();

。使Build方法作为默认值,我知道有一种方法,但我忘记了。

如何使构建方法默认为在c#构建器流畅接口中调用

好吧,我实际上不会推荐它,但最接近的情况是从FooBuilderFoo的隐式转换操作符:

public static implicit operator Foo(FooBuilder builder)
{
    return builder.Build();
}

然而,你需要让你的变量显式类型:

Foo foo = FooBuilder
             .WithSomething()
             .WithOtherthing();
顺便说一下,当你写FooBuilder的时候,你的是否真的是指new FooBuilder(),这并不清楚。我个人更喜欢创建具有可设置属性的构建器,这允许您使用对象初始化器。例如:
// With the implicit conversion from FooBuilder to Foo
Foo foo = new FooBuilder { Name = "Fred", Value = 10 };
// Without the implicit conversion
var foo = new FooBuilder { Name = "Fred", Value = 10 }.Build();

这是假设您实际上需要一个单独的FooBuilder类型。如果您乐意为每个"伪突变"创建Foo的新实例,那么您可以使用jure的选项。就我个人而言,我喜欢单独的Build方法,因为它意味着您可以在最后只执行

验证,这意味着您不需要担心操作的顺序,其中验证依赖于多个相关属性。

例如,如果您有一个具有DayOfMonthMonth属性的类型,并且您想要将"1月30日"更改为"2月20日",那么在"每一步创建一个新的验证对象"中,您需要首先更改月的日期,然后更改月份……但如果你要从"2月20日"到"1月30日",你就得反过来做了。使用单独的构建器类型和单个Build调用来验证最后的所有内容的方法意味着您无需担心。

如果您正在创建自己的构建器接口,则可以使用正在构建的类的扩展方法实现类似的功能

public static class FooExtensions
{
  public static Foo WithSomething(this Foo foo)
  {
    //do your thing with foo
    ....
    return foo;
  }
  public static Foo WithOtherthing(this Foo foo)
  {
     //do your thing with foo
    ....
     return foo;
  }
}

,然后用作

  var foo = new Foo().WithSomething().WithOtherthing();

FluentBuilder具有这样的行为是通过扩展方法实现的

public static class FluentBuilder
{
    public static Foo Build()
    {
        return new Foo();
    }
    public static Foo WithSomething(this Foo foo)
    {
        foo.Something = new Something();
        return foo;
    }
    public static Foo WithOtherThing(this Foo foo)
    {
        foo.OtherThing = new OtherThing();
        return foo;
    }
}

用法:

var foo1 = FluentBuilder.Build();
var foo2 = FluentBuilder.Build().WithSomething().WithOtherThing();
var foo3 = FluentBuilder.Build().WithOtherThing().WithSomething();