7

これは、シンプルで効率的なコードを生成するC#で可能であることを私は知っています。---同じクラスの2つのオブジェクトは、互いのプライベートパーツにアクセスできます。

class c1
{
    private int A;

    public void test(c1 c)
    {
        c.A = 5;
    }
}

しかし、F#では不可能に思えますが、本当ですか?

type c1()
     let A = 0
     member test (c: c1) = c.A
4

5 に答える 5

6

興味深い質問です。明示的なフィールドでは機能するようですが、letバインディングでは機能しません。

// Works
type c1 =
    val private A : int
    new(a) = { A = a }
    member m.test(c : c1) = c.A

let someC1 = new c1(1)
let someMoreC1 = new c1(42);
let theAnswer = someC1.test someMoreC1

// Doesn't work
type c2() =
    let mutable A = 42
    // Compiler error: The field, constructor or member 'A' is not defined
    member m.test(c : c2) = c.A 
于 2012-09-13T12:20:19.637 に答える
2

はい。ただし、この例Aでは、意味的にはのプライベートメンバーではなくc1、コンストラクターのローカル変数に似ています。

@afrischkeは、(フィールドを使用して)c1実際のプライベートメンバーで定義する方法の例を示しています。Aval

于 2012-09-13T12:14:46.537 に答える
1

aインスタンスメソッドで直接 使用するだけです

type c1()
     let A = 0
     member x.test = A

静的メソッドの場合、バインディングがわずかに異なるため、これは機能しません-次に、次のようなクラス定義が必要です

type c1()
     private member x.A = 0
     static member test (A:c1) = A.A
于 2012-09-13T12:04:23.940 に答える
1

F#仕様のセクション8.6.1 .3には、次のように記載されています。

インスタンス定義によって定義された関数と値は、定義されているオブジェクトに対して字句スコープ(したがって暗黙的にプライベート)になります。

于 2012-09-13T14:02:47.050 に答える
1

これは可能であり、たとえば、メンバーごとの同等性をチェックするために広く使用されています。

type c1 =
    member private this.A = 0
    interface IEquatable<c1> with
        member this.Equals (that: c1) = this.A = that.A
    // of course, it can be done in a regular method as well
    member this.Equals (that: c1) = this.A = that.A
于 2012-09-13T15:24:27.860 に答える