F#immutable类型如何与C#接口。我刚刚开始学习F#,我想把它与我的一些C#代码混合在一起,但我希望我的F#类是不可变的。
假设我们在F#中创建了一个Vector类。 Vector.X和Vector.Y应该是可重新赋值的,但只返回一个新的Vector类。在C#中,这需要花费大量的工作量.WithX(float x)克隆现有对象并返回一个新对象。在F#中有一种简单的方法吗?
我一直在寻找一些时间,我似乎无法找到任何关于此的文档。所以任何帮助都会很棒。
最后,如果我将这个类导入C#,它的界面会是什么样子? F#代码是否会限制我做像Vector.X = 10
这样的愚蠢行为?
答案 0 :(得分:8)
无论是C#还是F#,这看起来都很相似。
你说“在C#中它将需要腿部工作”,但cmon,我认为
Vector WithX(float x) { return new Vector(x, this.Y); }
是吗,对吗?
在C#和F#中,为了防止赋值给X属性,你创建了一个带有'getter'但没有'setter'的属性。
我认为你把所有这些都变得比现在更难,或者我误解了你的要求。
修改
对于(我认为罕见的)有20个字段的情况,你可能想要只更改它们的一小部分,我发现了一个可爱的hack很好地使用F#和C#可选参数。
F#代码:
namespace global
open System.Runtime.InteropServices
type Util =
static member Some<'T>(x:'T) = Some x
type MyClass(x:int, y:int, z:string) =
new (toClone:MyClass,
[<Optional>] ?x,
[<Optional>] ?y,
[<Optional>] ?z) =
MyClass(defaultArg x toClone.X,
defaultArg y toClone.Y,
defaultArg z toClone.Z)
member this.X = x
member this.Y = y
member this.Z = z
F#客户端代码:
let a = new MyClass(3,4,"five")
let b = new MyClass(a, y=44) // clone a but change y
C#客户端代码:
var m = new MyClass(3, 4, "five");
var m2 = new MyClass(m, y:Util.Some(44)); // clone m but change y
也就是说,可选参数是一种很好的方法,虽然C#可选参数有一些限制,但您可以以一种适用于C#的方式公开F#可选参数,如上所述。
答案 1 :(得分:6)
F#Record types有一种内置的方式可以完全满足您的要求:
type Vector = {X:float; Y:float}
let v1 = {X=1.; Y=2.}
let v2 = {v1 with X=3.}
如何与C#进行互操作,我不确定(编辑:请参阅Brian的评论)。
Vector将来自任何.NET语言,因为X和Y实现为没有setter的getter。