に固執しrecord
たいのですが、に戻りたくありませんobject
。だから私はのを作ることが可能かどうか疑問に思っていfield
ますrecord private
か?またはのを作成しprivate member
ますrecord
。他のconcrete types
ようなものはdiscriminated union
どうですか?
または、この要件は言語仕様に違反していますか?
に固執しrecord
たいのですが、に戻りたくありませんobject
。だから私はのを作ることが可能かどうか疑問に思っていfield
ますrecord private
か?またはのを作成しprivate member
ますrecord
。他のconcrete types
ようなものはdiscriminated union
どうですか?
または、この要件は言語仕様に違反していますか?
いいえ、単一のフィールドを非公開にすることはできません:http: //msdn.microsoft.com/en-us/library/dd233184
ただし、すべてのフィールドをプライベートにし、プロパティを介して選択したフィールドを公開することができます。'フィールドはプライベートであるため、レコードのインスタンスを作成するには、Create関数が必要になることに注意してください。
type MyRec =
private
{ a : int
b : int }
member x.A = x.a
member private x.Both = x.a + x.b // Members can be private
static member CreateMyRec(a, b) = { a = a; b = b }
MyRec.Both
上記のプロパティの場合のように、メンバーはプライベートにすることができます。
編集:上記は、フィールドをMyRecにプライベートではなく、MyRecが定義されているモジュールにプライベートにします。F#レコードのフィールドがプライベートとして宣言されている場合の奇妙なアクセシビリティスコープに対するダニエルの回答を参照してください。
この要件の問題は、レコードの言語機能ではプロパティがパブリックである必要があることです。たとえば、プロパティと書き込みを含むr
型のレコードがある場合、コンパイラはそれをに変換します。R
Name
Age
{ r with Age = 20 }
new R(r.Name, 20)
アイデアは、with
すべてのプロパティ(変更するプロパティを除く)をコピーするため、それらにアクセスできる必要があるということです。このため、コンパイラーは実際にあらゆる用途のメソッドを生成できwith
ますが、それによって多くのメソッドが生成される可能性があります。
レコードを好む理由は何ですか?それらには2つの優れた機能があります-with
キーワード(private
とにかくメンバーで失う)と構造的同等性(同じ値を持つ場合、2つのインスタンスは同じです)。それとは別に、いくつかのフィールドを非表示にしたい場合は、クラスの方が使いやすいようです。
これは簡単な例です(構造的平等を実装していません):
type R(name:string, age:int) =
member x.Name = name
member x.WithAge(newAge) = R(name, newAge)
フィールドでレコードを使用private
することは問題ないようですが、実装ファイル内でパブリックフィールドを使用し、すべての外部ユーザーのフィールドを非表示にするF#署名ファイルを使用する方が理にかなっている場合があります。このようwith
にして、実装のように機能を使用できますが、タイプは非表示になります。
それは不可能だと思います。MSDNによると:
レコードフィールドは、プロパティとして自動的に公開され、レコードの作成とコピーに使用されるという点でクラスとは異なります。レコードの構築もクラスの構築とは異なります。レコードタイプでは、コンストラクターを定義できません。
「自動的に公開される」はあなたの質問に答えるための鍵です。新しいタイプを作成したくない理由は3つありますか?