【问题标题】:Modelling large list of properties in C#在 C# 中对大量属性进行建模
【发布时间】:2014-10-23 22:14:54
【问题描述】:

我有一个对象可以拥有的 50 个属性的列表。此对象可以具有不同类别的属性 - 类别 1、类别 2 和类别 3。类别 1 是类别 2 的子集,类别 2 是类别 3 的子集,类别 3 是完整列表。我最初使用 struct 但我现在想知道是否应该使用类,或者我是否一开始就以错误的方式进行。为了方便起见,我们将其缩减为 5 个属性和 2 个类别。

C1: A1, A2, A3
C2: A1, A2, A3, A4, A5

我想做的主要事情是将结构或类保存在我的主类上,而不区分两者。如果我正在使用一个类,我可以创建一个可以派生 2 个类别类的基类并将其保存为基类:

Category category;
...
category = new Category1();
category = new Category2();

由于我要处理每个类别的 10、25、50 个属性,因此类定义只是一个大型属性列表,看起来 struct 会更合适。 但是如果我使用结构,看起来我必须将它保存为对象类型?这看起来很笨拙。

解决这个问题的正确方法是什么?


让我在这里偷偷问第二个问题。 :) 那么,由于每个类(或结构)都有大量属性列表,使用对象初始化器而不是具有 10、25、50 个参数的构造函数会更好吗?

【问题讨论】:

  • 一般来说,除非你有充分的理由,否则不要使用结构体。默认为类。结构是值类型,可能会导致意外行为,尤其是当您使它们可变时。同样因为它们是值类型,所以它们应该很小; 50 个成员对于一个结构来说太多了。
  • @Blorgbear - 谢谢。这就是我想得到一些反馈的原因。这些字段在成品中将是不可变的,但结构是值类型……但是 50 个字段太多了。等等等等。哈哈。看来我会坚持上课。

标签: c# class struct constructor object-initializers


【解决方案1】:

您应该只在以下情况下定义结构:

  • 表示单个值(类似于int、double、long、...)
  • 小于 16 个字节
  • 它是不可变的
  • 您不会期望它经常被装箱

我认为真正的问题是为什么你有一个包含 50 个属性的类。您可能应该考虑创建更小的逻辑类。

【讨论】:

  • 感谢您的回复。我不知道这种限制性的推荐做法。许多参考文献提到使用 struct 作为记录的占位符,所以我认为这可能是一个很好的用途。至于属性的数量,我目前正在编写一些解析粗略格式化数据的实验代码,并且我正在尝试基于它创建一个模型。我目前不确定如何在逻辑上构建它们。
【解决方案2】:

你打算用那个类别变量做什么?

使用类。我不认为你想要价值语义,而且你不会经常得到它们。数据太多。如果这些是 DTO,听起来您需要简单的旧类继承。

class Category1 {
  public int A1 { get; set; }
  public int A2 { get; set; }
  public int A3 { get; set; }
}

class Category2 : Category1 {
  public int A4 { get; set; }
  public int A5 { get; set; }
}

我会从初始化器开始,因为构造器是维护的。但是,如果您确实对它们进行了很多初始化,那么具有默认值的构造函数将允许您使用命名参数来产生很好的效果。所以,这取决于。

【讨论】:

  • 好吧,一旦设置了字段,我将让它们可用于分析器类的实例。字段一旦设置就不会改变,但我不确定是否将设置器设为私有,因为这意味着我不能使用对象初始化器。它仍然是一个实验性代码,所以我不太担心那种级别的语义。只想尽可能好地对数据进行建模。
  • 补充一下,我有当前设置的类作为你的例子,但我也有一个私有的设置器和构造器。而且,当我为类别 3 类设置构造函数时,参数列表变得如此之长,以至于我停下来,认为这不可能。在发布问题之前,我已将代码更改为看起来像您的示例并开始使用对象初始化程序。然后我决定就不同的方法征求一些建议。
【解决方案3】:

您可以创建类或结构,这取决于您将如何使用它们,但通常您应该只使用类。查看:http://msdn.microsoft.com/en-us/library/ms173109.aspx 了解更多详情。

在回答您的第二个问题时,应为没有良好默认值的 args 创建带参数的构造函数。否则对象初始化器很棒。

不过,您可能需要重新考虑您的设计。大多数设计良好的类不会有那么多属性。好的设计原则通常会指导您创建能够很好地完成一件事的方法,以及代表您正在建模的内容的最小表示的类。换句话说,如果您的类正在为汽车建模,那么它很可能具有由其他较小类表示的大型组件的属性。

【讨论】:

  • 谢谢。大多数字段只是原始类型,所以我相信它们有一个很好的默认值。正如我在 Kenneth 回答的评论中提到的那样,“我目前正在编写一些实验性代码来解析粗略格式化的数据,并且我正在尝试基于它创建一个模型。我目前不确定如何在逻辑上构建它们那一刻。”
【解决方案4】:

在许多情况下,将一个类的许多字段聚合到一个私有的暴露字段结构类型中会很有帮助。这样做的目的与经常被引用的“结构规则”文档的作者所设想的使用场景完全不同,因此其中的建议在这里没有意义。如果例如您将大多数主要字段封装到类型 PrimaryFieldStruct 中,并且您的类有一个名为 pf 的类型的字段,然后访问该结构的任何字段将与如果该字段是成员的成本相同类而不是结构的一部分。但是,将字段聚合为 PrimaryFieldStruct 类型将使您能够将所有字段从一个类实例复制到另一个类实例。

【讨论】:

    猜你喜欢
    • 2013-10-10
    • 2016-07-10
    • 2012-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 2012-10-15
    • 2017-06-03
    相关资源
    最近更新 更多