我现在正在开发一个系统,该系统处理具有相同原始 .NET 类型( double /字符串/整数)的语义不同值之间的大量转换。这意味着您可能会因为不转换或转换太多次而对您使用的“语义类型”感到困惑。理想情况下,如果我尝试使用语义上没有意义的值,我希望编译器发出警告/错误。
一些例子来说明我指的是什么:
- 角度的单位可能是度数或弧度,但两者都用
double
表示。 - 矢量位置可以在局部/全局坐标中,但两者都由
Vector3D
结构表示。 - 想象一个接受各种查询参数作为字符串的 SQL 库。最好有一种方法来强制只允许在运行时传入干净的字符串,而获得干净字符串的唯一方法是通过一些 SQL 注入(inject)攻击预防逻辑。
我相信 F# 对此有一个编译时解决方案(称为度量单位。)我想在 C# 中做类似的事情,尽管我不需要 F# 中的度量单位提供的维度分析。
我相信 C++ 可以使用 typedef
实现这一点(尽管我不是 C++ 专家)。
显而易见的解决方案是将 double /字符串/任何东西包装在一个新类型中,为它提供编译器需要的类型信息。我很好奇是否有人有替代解决方案。如果您确实认为包装是唯一/最好的方法,那么请深入探讨该模式的一些缺点(以及我没有提到的任何优点。)我特别关心抽象原始数字类型在我的计算机上的性能在运行时进行计算,因此无论我想出什么解决方案,在内存分配和调用调度方面都必须是轻量级的。
最佳答案
我真的很感兴趣,当你混合使用弧度和度数时,编译器是如何发出警告的。都是双标吗?你身处 OOP 世界,所以你应该走这条路。 两个建议:
- 内部只使用一个单位,我认为弧度更好。然后仅在输入/输出上转换。\
- 创建结构体
Degree
、Radian
并定义转换规则。或者创建“角度”类并在其中保存有关单位和转换的所有信息。
关于c# - 扩展 .NET 类型系统,以便编译器在某些情况下强制执行原始值的语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2945471/