Reputation: 21767
I know this is possible in C#, which produces simple and efficient code. --- Two objects of the same class can access each other's private parts.
class c1
{
private int A;
public void test(c1 c)
{
c.A = 5;
}
}
But It seems impossible in F#, is it true?
type c1()
let A = 0
member test (c: c1) = c.A
Upvotes: 7
Views: 752
Reputation: 25526
You just use a
directly in an instance method
type c1()
let A = 0
member x.test = A
For a static method this doesn't work as let bindings are slightly different - then you need a class definition like
type c1()
private member x.A = 0
static member test (A:c1) = A.A
Upvotes: 1
Reputation: 7735
This is possible and it is widely used, for example, for checking memberwise equality:
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
Upvotes: 1
Reputation: 55185
As section 8.6.1.3 of the F# spec states:
The functions and values defined by instance definitions are lexically scoped (and thus implicitly private) to the object being defined.
Upvotes: 1
Reputation: 3866
Interesting question. It seems to work with an explicit field but not with a let binding:
// 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
Upvotes: 6
Reputation: 22307
Yes, but in your example A
is not semantically a private member of c1
, it is more like a local variable of the constructor.
@afrischke gives an example of how to define c1
with an actual private member A
(using val
fields).
Upvotes: 2