let inline set (x: ^t) = BitConverter.ToUInt32(BitConverter.GetBytes(x),0)
我尝试了类似上面的内容,但它不起作用。类型约束或运行时解析类型都没有。另外,我猜测答案是否定的,但是可以告诉编译器泛型类型只是float32还是float?这会给我带来很多麻烦。
编辑:
令我感到惊讶的是,Tomas Petricek写的是有效的,反过来却没有:
let inline toUint32 conv x =
let bytes = conv x
BitConverter.ToUInt32(bytes, 0)
toUint32 BitConverter.GetBytes 9999.99f
toUint32 BitConverter.GetBytes 9999.99
这很有趣。如果没有其他帖子中的conv : BitConvertible
,我也无法使其发挥作用。
答案 0 :(得分:3)
静态成员约束不直接允许您编写将调用重载方法的内联函数。编译器无法决定是否对函数进行类型检查,就好像参数是float
或float32
或任何其他支持的类型一样。
简单的解决方案是将转换函数作为单独的参数传递:
let inline toUint32 x conv =
let bytes = conv x
BitConverter.ToUInt32(bytes, 0)
toUint32 9999.99f BitConverter.GetBytes
toUint32 9999.99 BitConverter.GetBytes
这需要更多的输入,但很容易看到发生了什么。调用者只需要提供一个执行转换的函数 - 在典型情况下,只需要BitConverter.GetBytes
。
另一种方法(在另一个答案中已经讨论过)是使用一个稍微狡猾的技巧,让你指定更多花哨的静态约束;这消除了传递显式函数的需要,只要它对最终用户隐藏,它就可以缩短你的代码。
答案 1 :(得分:2)
如果您准备做一些不寻常的事情,可以使用静态解析的类型约束来推广该函数。
请注意,这不适用于其他.NET语言 - 静态解析的类型约束完全是F#编译器的一项功能。
type BitConvertible =
|BitConvertible
static member Convert (conv : BitConvertible, flt : float) =
System.BitConverter.GetBytes(flt)
static member Convert (conv : BitConvertible, flt32 : float32) =
System.BitConverter.GetBytes(flt32)
module BitConverter =
let inline convertToBytes x =
((^T or ^U) : (static member Convert : ^T * ^U -> byte[]) (BitConvertible, x))
然后你可以使用它......
let a = BitConverter.convertToBytes 16.0
let b = BitConverter.convertToBytes 27.0f