代码之家  ›  专栏  ›  技术社区  ›  Drew Noakes

扩展.NET类型系统,以便编译器在某些情况下强制原语值的语义

  •  6
  • Drew Noakes  · 技术社区  · 14 年前

    我现在正在开发一个系统,处理具有相同原始.NET类型(double/string/int)的语义不同的值之间的大量转换。这意味着,可能会因为没有转换或转换太多次而混淆您正在使用的“语义类型”。理想情况下,如果我试图使用一个在语义上没有意义的值,我希望编译器发出警告/错误。

    一些例子来说明我指的是什么:

    • double .
    • 向量位置可以在局部/全局坐标中,但两者都用 Vector3D 结构。
    • 想象一下,一个SQL库接受各种查询参数作为字符串。最好有一种方法来强制在运行时只允许传递干净的字符串,而获得干净字符串的唯一方法是通过一些防止SQL注入攻击的逻辑。

    我相信F#有一个编译时解决方案(称为度量单位)。我想在C#中做一些类似的事情,尽管我不需要F#中度量单位提供的量纲分析。

    我相信C++可以实现这个 typedef (虽然我不是C++专家)。

    显而易见的解决方案是将double/string/whatever包装成一个新类型,以提供编译器所需的类型信息。我很好奇是否有人有别的解决办法。如果你真的认为包装是唯一/最好的方法,那么请谈谈这种模式的一些缺点(以及我没有提到的任何优点)。我特别关心抽象的原始数字类型在运行时的计算性能,因此,无论我提出什么解决方案,在内存分配和调用调度方面都必须是轻量级的。

    3 回复  |  直到 14 年前
        1
  •  4
  •   Andrey    14 年前

    我真的很感兴趣的编译器如何给出警告,当你混合弧度和度。它们都是双人的吗?你在OOP世界,所以你应该走这条路。 两条建议:

    1. 内部只使用一个单位,我认为弧度更好。然后仅在输入/输出时转换\
    2. 创建结构 Degree , Radian 定义转换规则。或者创建类“Angle”并保存所有关于单位和转换的信息。
        2
  •  3
  •   Brian Gideon    14 年前

    Math 功能。

    public struct Degrees
    {
      private double m_Value;
    
      public static explicit operator Radians(Degrees rhs)
      {
        return rhs.m_Value * (Math.Pi / 180);
      }
    }
    
    public struct Radians
    {
      private double m_Value;
    
      public static implicit operator double(Radians rhs)
      {
        return rhs.m_Value;    
      }
    }
    
        3
  •  0
  •   Scott Weinstein    14 年前

    我从来没有找到一个令人满意的解决这类问题的方法。似乎类型系统不是为这个用例设计的。如果我现在也有同样的需求,我会研究F#度量单位方法。

    推荐文章