It will look the same whether C # or F #.
You say: βIn C # it will workβ, but cmon, I think
Vector WithX(float x) { return new Vector(x, this.Y); }
it is right?
In both C # and F #, to prevent the assignment of the X property, you create the property using "getter", but not "setter".
I think you make it all more difficult than it is, or maybe I donβt understand what you are asking.
EDIT
For the case (I think itβs rare), where there are 20 fields, and you may want to change only a small arbitrary subset of them, I found a nice hack to make good use of the F # and C # parameters.
F # Code:
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
Customer Code F #:
let a = new MyClass(3,4,"five") let b = new MyClass(a, y=44)
C # client code:
var m = new MyClass(3, 4, "five"); var m2 = new MyClass(m, y:Util.Some(44));
That is, optional parameters are a good way to do this, and while additional C # parameters have some limitations, you can provide additional F # parameters in such a way that this is normal with C #, as suggested above.