繁体   English   中英

如何实例化一个大的不可变类型?

[英]How to instantiate a large immutable type?

我有一个类型,有大约40个属性(所有值类型),代表我的业务的一种交易。 此类的实例对应于我的数据库中的一行。 我想保持我的类不可变,因为它只会用于读取操作,但我不知道如何在初始化期间设置40个属性。

通常我对不可变类型使用构造函数初始化,但我想避免编写带有40个参数的构造函数。 我的房产的安装人员目前是私人的,但我愿意以足够的理由改变。 是否有一种常见的方法来处理这种情况或更好的方法来解决问题?

你的问题不是一个有40个参数的构造函数,而是一个有40个字段的类。

我建议打破这个。 是否有任何相关领域? 如果是这样,将它们分组到一个公共对象(例如EmailInfo),然后让你的大对象引用分组对象。

// Instead of this:
foo.EmailHeader
foo.EmailSubject
foo.Email...

// Do this:
foo.Email.Header
foo.Email.Subject

一旦你的类具有较少的直接属性,创建一个获取这些分组对象的构造函数并不是那么糟糕。

快点。 你提到你对象的setter是私有的。 如果是这种情况,那么您的对象不是不可变的(否则setter不存在)。 最好你的对象是只读的。

对于一个真正的不可变对象,别无选择,只能让构造函数接受初始化对象所需的所有值。 减少构造函数中参数数量的最佳方法是将值分组为更大的对象,然后将这些对象传递给构造函数。 虽然我不会这样做,除非这些值在逻辑上是相关的。

如果你的不可变类型确实需要40个值而且它们不相关,那么最好的方法是使用一个具有40个值的构造函数。 那还是进一步打破了大不可变对象。

我喜欢使用可变对象来实例化不可变对象的方法; 可变对象只是为了整理选项。 .NET框架中的一个例子是ProcessStartInfo

class XInfo {
  public int A;
  public int B;
}

class X {
  public X (XInfo i) {
    // you can transform the data/layout from i any way you need
    ..
  }
}

new X(new XInfo() {
  A = 42
})

虽然我会对'40属性'保持缄默,但我发现上述方法效果很好。 另外一个好处是XInfoX使用的内部结构可以完全不同,只要您可以提供合理的映射。

如果我按照你的说法“但我不确定如何在初始化期间设置40个属性。”,看来你的问题是一个具有太多字段/属性的类。 似乎不是让它变得不可变的问题,因为你已经知道如何做到这一点。

我会建议(像其他人一样),Refactor和Extract Class。

作为替代方案,您可以使您的类派生自freezable ,我认为这可能是您正在寻找的解决方案。 您可以对对象进行Instatiate,设置值,然后将其设置为冻结。 一旦你将它设置为冻结,该类就是“只读”。

我建议将参数放入一个或多个结构中,让对象保存这些结构。 嵌套对象是可能的,但是会比嵌套结构增加更多的开销。

作为替代方案,您可以使用所有属性的“readonly mustoverride”版本创建一个抽象基类。 由此,派生出一个可变且不可变的对象类。 不可变的可以在其构造函数中接受基类,并使用所有readonly属性来构建新对象。 可变类可以提供使用方法编写属性的方法,具有来自只读版本的不同名称的读写属性等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM