Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 一个对象是否可以访问同一类的另一个对象的私有字段/函数?_F# - Fatal编程技术网

F# 一个对象是否可以访问同一类的另一个对象的私有字段/函数?

F# 一个对象是否可以访问同一类的另一个对象的私有字段/函数?,f#,F#,我知道这在C#中是可能的,C#生成简单高效的代码同一类的两个对象可以访问彼此的私有部分 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 您只需在实例方法中直接使用a type c1() let A = 0

我知道这在C#中是可能的,C#生成简单高效的代码同一类的两个对象可以访问彼此的私有部分

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

您只需在实例方法中直接使用
a

type c1()
     let A = 0
     member x.test = A
对于静态方法,这不起作用,因为let绑定略有不同-然后需要一个类定义,如

type c1()
     private member x.A = 0
     static member test (A:c1) = A.A

是的,但是在您的示例中,
A
在语义上不是
c1
的私有成员,它更像是构造函数的局部变量


@afrischke给出了一个示例,说明如何使用实际的私有成员
A
(使用
val
字段)定义
c1

一个有趣的问题。它似乎适用于显式字段,但不适用于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 
正如《F#spec》第3节所述:

实例定义定义的函数和值在词汇上限定(因此隐式私有)于所定义的对象


这是可能的,并且广泛用于检查成员平等性:

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
类型c1=
成员private this.A=0
接口与
成员this.Equals(that:c1)=this.A=that.A
//当然,也可以用常规方法进行
成员this.Equals(that:c1)=this.A=that.A

您对
c1
的定义有一些语法错误,无法编译,访问
c.A
的尝试无效。第二个示例中的问题:您无法从静态方法访问成员。不,A不是本地构造函数值。事实上,它是一个私有成员,请参见。@JohnReynolds-我说它“更像”一个本地构造函数值,而不是说它“是”一个。“事实上,它是一个私有成员”:MSDN在这里有误导性,它被编译到一个私有字段,但这是一个实现细节。从语义上讲,它与专用可访问性的CLI定义不兼容(请参见第I.8.5.3.2节)。当然,对于“更像构造函数的局部变量”的含义,人们可能有不同的看法。我的解释是,
A
只能在构造函数内部访问。这里的情况并非如此,因为
A
可供
c1
的同一实例的所有成员函数访问(尽管不可供
c1
的其他实例访问)。这是一个解决办法,但这里
A
是一个属性,而不是字段。@Daniel没有证据表明OP是否需要字段。:)<代码>设A=0可能只是一个错误。另外,@afrischke的答案似乎足以用于显式字段。标题询问是否可以访问私有字段。他的C#示例也使用字段。