2012-09-13 14 views
6

Sé que esto es posible en C#, que produce un código simple y eficiente. --- Dos objetos de la misma clase pueden acceder a las partes privadas de cada uno.¿Es posible que un objeto tenga acceso a un campo/función privada de otro objeto de la misma clase?

class c1 
{ 
    private int A; 

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

Pero parece imposible en F #, ¿es cierto?

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

Su definición de 'c1' tiene algunos errores de sintaxis y no compila, intento no válido en el acceso a' cA' aparte. –

Respuesta

5

Interesante pregunta. Parece que funciona con un campo explícita pero no con la unión 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

Usted sólo tiene que utilizar a directamente en un método de instancia

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

Para un método estático esto no funciona como se permiten enlaces son ligeramente diferente - entonces usted necesita una definición de clase como

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

Problema en el segundo ejemplo: no puede acceder a los miembros desde un método estático. –

+0

@JohnReynolds - corregido –

2

Sí, pero en su ejemplo A no es semánticamente un miembro privado de c1, es más como una variable local del constructor.

@afrischke da un ejemplo de cómo definir c1 con un miembro privado real A (usando los campos val).

+0

No, A no es un valor de constructor local. De hecho, es un miembro privado, consulte http://msdn.microsoft.com/en-us/library/dd483470. –

+1

@JohnReynolds - Dije que era "más como" un valor de constructor local, no es que "sea" uno. "De hecho, es un miembro privado": MSDN es engañoso aquí, * está * compilado en un campo privado, pero eso es un detalle de implementación. Semánticamente no es compatible con la definición de CLI de accesibilidad privada (ver http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-335.pdf, sección I.8.5.3.2) –

+0

Por supuesto, uno puede tener diferentes vistas de lo que significa "más como una variable local del constructor". La forma en que interpreto eso, es que 'A' solo es accesible dentro del constructor. Ese no es el caso aquí, ya que 'A' es accesible para todas las funciones miembro de la misma instancia de' c1' (aunque no para otras instancias de 'c1'). –

1

Como la sección 8.6.1 0.3 de los estados # spec F:

Las funciones y valores definidos por las definiciones de instancia están en el ámbito léxico (y por lo tanto implícitamente privado) al objeto que se está definiendo.

1

Esto es posible y que es ampliamente utilizado, por ejemplo, para comprobar la igualdad miembro por miembro:

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 
+1

Esto es una solución, pero aquí 'A' es una propiedad, no un campo. – Daniel

+0

@Daniel No hay evidencia si el OP necesita campos. :) 'let A = 0' puede ser solo un error. También la respuesta de @ afrischke parece ser suficiente para campos explícitos. – bytebuster

+1

El título pregunta si es posible acceder a campos privados. Su ejemplo de C# también usa campos. – Daniel

Cuestiones relacionadas