如何创建类型安全的数值类型?

问题描述 投票:0回答:1

背景

假设我正在编写一个关于蛋糕的应用程序。
我需要存储蛋糕的重量(公斤)及其 FCR(糖霜/巧克力比率。我编的)。我可以将这些值存储为

float
。我看到的问题是我可以将重量(公斤)值分配给 FCR 字段

C# 的类型系统可以防止此类错误。如果我创建一个

class WeightInKg
和一个
class FrostingChocolateRatio
,我将无法将其中一个分配给另一个。

问题

然后我需要再次实现所有数字运算符(

+ - * / > < ==
等)。这些实现起来已经很烦人了,因为它们只是
float
功能的包装。然而,由于这些结构都是基于 float
both
,所以所有这些包装器方法实际上都是相同的。对于所有其他此类基于
float
的类型来说,情况也是如此。

我尝试过/想过什么

  • 良好的旧 OO 继承。
    abstract class FloatValue
    可以提供所有数值运算,但这些操作随后返回
    FloatValue
    类型而不是(类型安全)子类类型。我还觉得结构应该用于本质上是基本值的东西,并且结构不支持子类。
  • 泛型。我目前正在使用这个; a
    struct Quantity<T>
    已执行所有数值运算。对于
    T
    ,我然后使用空的“标记类”,它仅用于识别某种类型的数量(例如
    FrostingChocolateRatio
    )。这是可行的,但不断使用
    Quantity<WhatIReallyWant>
    会很尴尬,并且会在代码中产生更多的视觉混乱。

问题

这是否最接近我想要的,或者是否有更干净的方法在 C# 中拥有此类类型安全值?

添加

正如 PaulF 提到的,

FrostingChocolateRatio
不是一个理想的例子,因为比率的数学运算方式不同。然而,我今天已经没有创造力了;假设它与
WeightInKg
完全相同。
重点是,有几种不同类型的值的行为与
float
完全相同,但在一升中添加一厘米是没有意义的。

c# types
1个回答
0
投票

今天又一时兴起发现了这个,哇,六年了——同时有两件事发生了变化。

首先是我作为开发者的经历。当时,将相同的代码复制粘贴到几个不同的部分感觉“错误”。有一个数值,例如无法分割感觉不完整。
然而,从我目前的观点来看......我们并不是试图编写一个功能完整的数字库。我们需要对 2 或 3 种不同类型的值进行一些操作。在需要的地方复制粘贴代码绝对足够了,也是解决这个问题最省时的方法。

第二部分是技术方面。在 .NET Core 中,默认的 .NET 数字类型现在使用一长串接口,每个接口都描述了可能操作的一小部分。这是在这种情况下挑选和选择实际需要的零件的完美选择:

  public readonly struct UInt64 : 
    IComparable,
    IConvertible,
    ISpanFormattable,
    IFormattable,
    IComparable<ulong>,
    IEquatable<ulong>,
    IBinaryInteger<ulong>,
    IBinaryNumber<ulong>,
    IBitwiseOperators<ulong, ulong, ulong>,
    INumber<ulong>,
    IComparisonOperators<ulong, ulong, bool>,
    IEqualityOperators<ulong, ulong, bool>,
    IModulusOperators<ulong, ulong, ulong>,
    INumberBase<ulong>,
    IAdditionOperators<ulong, ulong, ulong>,
    IAdditiveIdentity<ulong, ulong>,
    IDecrementOperators<ulong>,
    IDivisionOperators<ulong, ulong, ulong>,
    IIncrementOperators<ulong>,
    IMultiplicativeIdentity<ulong, ulong>,
    IMultiplyOperators<ulong, ulong, ulong>,
    ISpanParsable<ulong>,
    IParsable<ulong>,
    ISubtractionOperators<ulong, ulong, ulong>,
    IUnaryPlusOperators<ulong, ulong>,
    IUnaryNegationOperators<ulong, ulong>,
    IUtf8SpanFormattable,
    IUtf8SpanParsable<ulong>,
    IShiftOperators<ulong, int, ulong>,
    IMinMaxValue<ulong>,
    IUnsignedNumber<ulong>,
    IBinaryIntegerParseAndFormatInfo<ulong>
© www.soinside.com 2019 - 2024. All rights reserved.