F# 在F中没有度量值的情况下,如何创建度量记录类型#
我在公共库(LibRoot)中定义了一个记录类型,该库由C#(LibC)和F#(LibF)代码使用 然后,我在C#library(LibC)中编写了一个公共API,F#library(LibF)使用它。但每当我试图将一个对象传递给这个API时,F#都会抱怨它必须有一个度量单位F# 在F中没有度量值的情况下,如何创建度量记录类型#,f#,interop,records,units-of-measurement,F#,Interop,Records,Units Of Measurement,我在公共库(LibRoot)中定义了一个记录类型,该库由C#(LibC)和F#(LibF)代码使用 然后,我在C#library(LibC)中编写了一个公共API,F#library(LibF)使用它。但每当我试图将一个对象传递给这个API时,F#都会抱怨它必须有一个度量单位 //LibRoot - F# type Vec2<[Measure] 'u> = { X : int Y : int } //LibF-F# 开放式LibC 设myVec:Vec2={X=12
//LibRoot - F#
type Vec2<[Measure] 'u> = {
X : int
Y : int
}
//LibF-F#
开放式LibC
设myVec:Vec2={X=123;Y=456}
DoWork(myVec)//FS0001
错误FS0001:类型不匹配。预期为“Vec2”,但给定“Vec2”,元组具有
不同长度的0和1
我试过:
:FS0001Vec2
:类型中的文字无效Vec2
:类型中出现意外“')Vec2
:FS0001Vec2
:预期的度量单位,而不是类型Vec2
:没有可用于类型“Vec2”的构造函数。如注释中所述,度量单位是在编译的.NET代码中没有表示形式的F#唯一特性,因此当您使用C#中带有单位注释的类型时,它将显示为没有单位的类型 编译后的C#代码不会包含特殊的F#元数据,以表明这是一个单元注释类型,因此引用C#库的F#编译器不会将其识别为单元注释类型。可以说,F#编译器可以更智能地解决这个问题(因为它可以发现(Vec2)myVec
类型最初来自F#) 我认为没有一种安全的方法可以将未测量的Vec2
转换为测量的Vec2
,但使用Vec2
的不安全转换将在运行时起作用:unbox
let v : LibRoot.Vec2<1> = { LibRoot.Vec2.X = 1; Y = 2 } LibCs.Funcs.DoWork(unbox v)
让v:LibRoot.Vec2={LibRoot.Vec2.X=1;Y=2} LibCs.Funcs.DoWork(unbox v)
我认为没有一种方法可以在F#code中明确地引用类型
(无量度),但是Vec2
可以很好地推断类型。这不是很好,所以如果您经常需要这种转换,那么最好重新设计您的库,以便C#使用不带单位的单独类型。Tomas的答案是正确的。我将为后代分享我的工作方法 我的度量单位是unbox
[<Measure>] type Absolute [<Measure>] type Relative
我引入了可转换为[]输入绝对值 []类型相对
进行互操作的“具体”记录类型。比如说Vec2
type Offset2 = { X : int Y : int } with static member ofVec (vec : Vec2<Relative>) : Offset2 = { X = vec.X; Y = vec.Y } static member toVec (off: Offset2) : Vec2<Relative> = { X = off.X; Y = off.Y }
type Offset2={ X:int Y:int } 具有 vec的静态成员(vec:Vec2):Offset2={X=vec.X;Y=vec.Y} 静态成员toVec(off:Offset2):Vec2={X=off.X;Y=off.Y}
我将它们转换为Vec2来执行数学运算,但对公共API使用“具体”类型。有额外的类型有点烦人,但它可以工作。可能无法完成,度量单位信息在编译后基本上会丢失。[<Measure>] type Absolute [<Measure>] type Relative
type Offset2 = { X : int Y : int } with static member ofVec (vec : Vec2<Relative>) : Offset2 = { X = vec.X; Y = vec.Y } static member toVec (off: Offset2) : Vec2<Relative> = { X = off.X; Y = off.Y }