簡體   English   中英

F#不可變類Interop

[英]F# Immutable Class Interop

F#immutable類型如何與C#接口。 我剛剛開始學習F#,我想把它與我的一些C#代碼混合在一起,但我希望我的F#類是不可變的。

假設我們在F#中創建了一個Vector類。 Vector.X和Vector.Y應該是可重新賦值的,但只返回一個新的Vector類。 在C#中,這需要花費大量的工作量.WithX(float x)克隆現有對象並返回一個新對象。 在F#中有一種簡單的方法嗎?

我一直在尋找一些時間,我似乎無法找到任何關於此的文檔。 所以任何幫助都會很棒。

最后,如果我將這個類導入C#,它的界面會是什么樣的? F#代碼是否會限制我做一些像Vector.X = 10這樣愚蠢的事情?

無論是C#還是F#,這看起來都很相似。

你說“在C#中它會需要腿部工作”,但我認為是cmon

Vector WithX(float x) { return new Vector(x, this.Y); }

這樣對嗎?

在C#和F#中,為了防止賦值給X屬性,你要創建一個帶有'getter'但沒有'setter'的屬性。

我認為你所做的一切都比現在更難,或者我誤解了你的要求。

編輯

對於(我認為罕見的)有20個字段的情況,你可能想要改變它們的一小部分,我發現一個可愛的黑客很好地使用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#可選參數,如上所述。

F# 記錄類型有內置的方式來完成你所要求的:

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。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM