我可以不使用'new'这么多

本文关键字:new 我可以 | 更新日期: 2023-09-27 18:12:04

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

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的情况下实现相同的结构吗?
我能对我的构造函数做些什么使之成为可能吗?

我可以不使用'new'这么多

如果在A的默认构造函数中创建了新的B 's,在B的默认构造函数中创建了C's,则可以将其简化为A a = new A();

class A{
    public A() : this(new B1(), new B2())
    {
    }
    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() : this(new C1(), new C2(), new C3())
    {
    }
    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() : this(new C1(), new C2(), new C3())
    {
    }
    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{}
public static void Main()
{
    A a = new A();
}

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

例如,使用autoface你可以这样做:

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>();

对于您的简单示例来说,这可能看起来有点小题大做,但如果您真的要组成一个复杂的对象图,那么就需要考虑一下。

不,没有new关键字创建新对象,你能做的是在构造函数中添加可选参数。

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();
      }
}

但是这对于不可变对象来说没有什么意义,最好让它们为空,因为它只会无缘无故地使用内存