これは、C#でもF#でも同様です。
あなたは "それは取材がかかりますC#で" と言うが、CMON、私は
Vector WithX(float x) { return new Vector(x, this.Y); }
は右、それはあると思いますか?
C#とF#の両方で、Xプロパティへの割り当てを禁止するには、 'getter'を持つプロパティを作成しますが、 'setter'は作成しません。
私はあなたがこれよりももっと難しくなっていると思っています。あるいは、あなたが求めていることを誤解しているかもしれません。そこに20フィールドであり、あなたはそれらのほんの任意のサブセットを変更することがありどこの(私は稀だと思う)場合のためにEDIT
は、私が一緒に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#オプションのパラメータを公開することができます上のted。
はい、これは簡単です。しかし、私が一人のクラスに20人のメンバーをいればどうなりますか?その場合、コンストラクタを呼び出すよりも "WithX(40)"を持つ方がずっと簡単です。多くの場合、そのクラスのメンバーから1人のメンバーを変更するだけでよいので、コンストラクターの引数としてそれらをすべて綴ると、少し冗長になります。 –
そして、Z値を受け入れるようにVectorクラスを変更したいとしたら、WithX()、WithY()とVectorコンストラクタを変更して変更する必要があります。 –
Stephenが指摘するように、レコードタイプはこの機能を提供します。代わりにクラスが必要な場合は、[this one](http://stackoverflow.com/questions/2873125/f-record-member-evaluation/2885063#2885063)などの回避策を使用できます。 – Daniel