我知道这在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
答案 0 :(得分:5)
有趣的问题。它似乎使用显式字段,但不使用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
答案 1 :(得分:2)
是的,但在您的示例中,A
在语义上不是c1
的私有成员,它更像是构造函数的局部变量。
@afrischke举例说明如何使用实际私有成员c1
定义A
(使用val
字段)。
答案 2 :(得分: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
答案 3 :(得分:1)
作为F#规范的第8.6.1。3节说明:
实例定义定义的函数和值在词法范围内(因此隐式私有)到正在定义的对象。
答案 4 :(得分: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