我可以在不使用“新”的情况下构建合成类。非常?

时间:2016-10-06 15:12:54

标签: c# class constructor composition

我有一个基本的类型组合:

class A{
    public A(B1 b1, B2 b2){
        this.b1 = b1;
        this.b2 = b2;
    }
    public B1 b1 {get; private set;}
    public B2 b2 {get; private set;}
}

class B1{
    public B1(C1 c1, C2 c2, C3 c3){
        this.c1 = c1;
        this.c2 = c2;
        this.c3 = c3;
    }
    public C1 c1 {get; private set;}
    public C2 c2 {get; private set;}
    public C3 c3 {get; private set;}
}
class B2{
    public B2(C1 c1, C2 c2, C3 c3){
        this.c1 = c1;
        this.c2 = c2;
        this.c3 = c3;
    }
    public C1 c1 {get; private set;}
    public C2 c2 {get; private set;}
    public C3 c3 {get; private set;}
}

class C1{}
class C2{}
class C3{}

是否有更简洁的方法来构建A

public static void Main()
{
    A a = new A(new B1(new C1(), new C2(), new C3()), new B2(new C1(), new C2(), new C3()));
}

我可以在不使用new的情况下实现相同的构造吗? 我能为我的构造者做些什么才能做到这一点?

3 个答案:

答案 0 :(得分:3)

如果在A的默认构造函数中它创建了新的B,并且在B的默认构造函数中创建了C,则可以将其简化为{{1} }

A a = new A();

答案 1 :(得分:2)

在编写类型时考虑的另一种选择,特别是如果你想避免硬编码new以获得更好的依赖注入,就是使用依赖容器。

例如,使用Autofac即可:

var builder = new ContainerBuilder();

builder.RegisterType<A>();
builder.RegisterType<B1>();
builder.RegisterType<B2>();
builder.RegisterType<C1>();
builder.RegisterType<C2>();
builder.RegisterType<C3>();

var container = builder.Build();

var a = container.Resolve<A>();

对于你的简单例子来说,这似乎有些过分,但如果你真的要编写一个复杂的对象图,那么就需要考虑。

答案 2 :(得分:0)

没有新的关键字创建一个新对象,你可以做的是在构造函数中有可选的参数。

class A
{

//Proper Immutable property works only c# 6 
      public B1 B1 { get; }
      public B2 B2 { get; }
      public A(B1 b1 = null, B2 b2 = null)
      {
           B1 = b1??new B1();
           B2 = b2??new B2();
      }
}

但这对于不可变对象没有多大意义,最好不要将它们保留为null,因为它只会毫无理由地使用内存。