我陷入了经典设计的困境。我正在编写一个包含值和测量单位元组(例如 7.0 毫米)的 C# 数据结构,我想知道是否应该使用引用类型或值类型。
结构的好处应该是更少的堆操作,让我在表达式中获得更好的性能,并减少垃圾收集器的压力。对于像这样的简单类型,这通常是我的选择,但在这种具体情况下存在缺点。
元组是相当通用的分析结果框架的一部分,其中结果在 WPF 应用程序中以不同的方式呈现,具体取决于结果值的类型。WPF 使用它的所有数据模板、值转换和模板选择器处理这种弱类型非常好。这意味着如果我的元组表示为结构,则该值将经历大量装箱/拆箱。事实上,元组在表达式中的使用对于装箱场景中的使用来说是次要的。为了避免所有的拳击,我考虑将我的类型声明为一个类。另一个对结构体的担忧是,WPF 中的双向绑定可能存在缺陷,因为在代码中的某处得到元组的副本而不是引用副本会更容易。
我也有一些方便的运算符重载。我可以使用重载的比较运算符将毫米与厘米进行比较,而不会出现问题。但是,如果我的元组是一个类,我不喜欢重载 == 和 != 的想法,因为约定是 == 和 != 是引用类型的 ReferenceEquals(与 System.String 不同,这是另一个经典讨论)。如果 == 和 != 被重载,有人会写if (myValue == null)并在有一天 myValue 为 null 时得到一个讨厌的运行时异常。
另一个方面是,在 C# 中(与例如 C++ 不同)没有明确的方法来区分代码使用中的引用类型和值类型,但语义却非常不同。我担心我的元组(如果声明为结构)的用户假定类型是一个类,因为大多数自定义数据结构都是并且假定引用语义。这是另一个论点,为什么人们应该更喜欢类,因为那是用户所期望的并且没有“。” /“->”来区分它们。一般来说,除非我的分析器告诉我使用结构,否则我几乎总是使用类,这仅仅是因为类语义最有可能被其他程序员所期望,而 C# 只是模糊地暗示它是一件事还是另一件事。
所以我的问题是:
在决定是否应该进行价值或参考时,我应该考虑哪些其他因素?
== / != 在任何情况下都可以证明类中的重载是合理的吗?
程序员假设东西。大多数人可能会认为所谓的“点”是一种值类型。如果您阅读一些带有“UnitValue”的代码,您会假设什么?
鉴于我的使用说明,您会选择什么?