如何避免在.NET中为不同的数字类型编写重复代码

iro*_*nic 3 c# f# numbers dry nemerle

我正在尝试编写通用的Vector2类型,它将包含float,double等类型并使用算术运算.有没有机会在C#,F#,Nemerle或任何其他或多或少成熟的.NET语言中做到这一点?

我需要一个解决方案

  • (1)良好的性能(与我编写单独的Vector2Float,Vector2Double等类相同),
  • (2)这将允许代码看起来不错(我不想在运行时为每个类发出代码)
  • (3)并尽可能多地进行编译时检查.

由于原因1和3,我不想使用动态.现在我正在检查F#和Nemerle.

UPD:我希望这种类型有很多数学代码.但是,如果可能的话,我更愿意将代码放在扩展方法中.

UPD2: 'etc'类型包括int(我实际上怀疑我会使用)和decimal(我想我可以使用,但现在不是).使用扩展方法只是一个品味问题 - 如果有充分理由不这样做,请告诉我们.

Tom*_*cek 8

正如Daniel所提到的,F#有一个称为静态解析类型参数的功能,它超出了你在C#中使用普通.NET泛型的功能.诀窍在于,如果将函数标记为inline,则F#自动生成专用代码(有点像C++模板),然后您可以使用F#类型系统的更强大功能来编写泛型数学.

例如,如果您编写一个简单的添加函数并将其创建inline:

let inline add x y = x + y;;    
Run Code Online (Sandbox Code Playgroud)

类型推断打印以下类型:

val inline add :
  x: ^a -> y: ^b ->  ^c
    when ( ^a or  ^b) : (static member ( + ) :  ^a *  ^b ->  ^c)
Run Code Online (Sandbox Code Playgroud)

您可以看到推断类型相当复杂 - 它指定了一个成员约束,它需要两个参数之一来定义一个+成员(标准.NET类型也支持这一点)好的是这可以完全推断出来,所以你很少会写丑陋的类型定义.

正如评论中所提到的,我写了一篇文章编写通用数字代码,详细介绍了如何在F#中执行此操作.我不认为这可以在C#中轻松完成,并且您在F#中编写的内联函数只能从F#调用(从C#调用它们本质上将使用动态).但你绝对可以在F#中编写通用数值计算.