代码之家  ›  专栏  ›  技术社区  ›  mezoid

如何在C#中为具有引用类型属性的对象创建生成器?

  •  0
  • mezoid  · 技术社区  · 16 年前

    我已经开始构建一个构建器,以便可以轻松地为我正在编写的单元测试创建测试数据。

    建造商的基本结构是:

    public class MyClassBuilder
    {
        public int id = 0; //setting the default value here
    
        //allows MyClass to be built with a specific id
        public MyClassBuilder WithId(int id)
        {
            this.id = id;
            return this;
        }
    
        public MyClass Build()
        {
            return new MyClass(id);
        }
    }
    

    MyClass mc = new MyClassBuilder().WithId(5).Build();
    

    我对此很满意……但我有疑问的是什么时候 MyClass

    public class MyClassBuilder
    {
        public int id = 0; //setting the default value here
    
        //do I construct the default value using a MySecondClassBuilder?
        public MySecondClass mySecondClass;
    
        //allows MyClass to be built with a specific id
        public MyClassBuilder WithId(int id)
        {
            this.id = id;
            return this;
        }
    
        public MyClassBuilder WithMySecondClass(MySecondClass mySecondClass)
        {
            this.mySecondClass = mySecondClass;
        }
    
        public MyClass Build()
        {
            return new MyClass(id);
        }
    }
    

    我的假设是,我将为 MySecondClass 并使用它创建默认实现。

    有人能证实我的假设是正确的,是最佳实践吗?

    我目前正在测试我的假设,但我想我会在StackOverflow上记录这个想法,因为我能找到的构建器模式的唯一示例是使用google构建的属性,它们是值类型而不是引用类型。

    2 回复  |  直到 14 年前
        1
  •  1
  •   Reed Copsey    16 年前

    和大多数事情一样,这要看情况而定。

    如果您想在mySecondClass字段中使用引用语义(即:您想保存对另一个类的引用),那么它与您的整数完全相同。默认值为null完全可以接受。

    但是,如果希望始终保证值,则需要为第二个类构建或仅构建一个新对象。

    此外,如果希望克隆而不是引用副本,则需要构造一个新对象并将其分配给引用。

    例如,在您的代码中,如果用户从不调用Build,会发生什么?它仍然返回一些东西(因为每个方法都返回一个对象),但是它有效吗?作为你们班的消费者,我不敢肯定。另一方面,传统的重载构造函数确切地告诉我什么是有效的,什么是无效的,并且是编译时强制的。

        2
  •  0
  •   McMuttons    16 年前

    这样做的好处是,它们通常能够使用默认值和空对象删除原始类型中存在的所有属性,而无需执行任何操作(除了单行语句)来创建伪对象。同时,您可以轻松地配置对象,以返回与测试相关的属性的值。而且,大多数这样的框架都支持递归伪造,因此类型中的复杂对象也会被伪造,等等。

    如果没有任何理由避免添加模拟框架(假设您已经分离了测试,那么它只会是您的测试项目的依赖项),我衷心推荐它用于复杂类型。

    推荐文章