.net - que - F#realmente compila miembros privados como internos en IL. ¿Error?
el modificador public no es valido para este elemento (1)
Siempre asumí que las palabras clave de control de acceso en F # ( public
, private
, internal
) funcionan de la misma manera que en C #. De hecho, desde la documentación de MSDN Control de acceso (F #) :
- público indica que todas las personas que llaman pueden acceder a la entidad.
- interno indica que solo se puede acceder a la entidad desde el mismo conjunto.
- privado indica que solo se puede acceder a la entidad desde el tipo o módulo adjunto.
Esto parece ser bastante consistente con mi suposición y también con múltiples respuestas sobre el tema proporcionadas aquí en SO.
Sin embargo, cuando ingresé en el código compilado con Reflector, descubrí que todos los miembros declarados como privados se compilan realmente como internos (visibilidad del ensamblaje), lo que no coincide con la documentación.
Para evitar cualquier duda, he creado una pequeña prueba para confirmar esto.
Código F #:
// Make internals visible to other assemblies
[<assembly:InternalsVisibleTo("MyCSharpAssembly")>]
// OK. Expect: "internal static class PrivateModule" in C#
module private PrivateModule =
// FAIL. Expect: "private static void privateStaticMethod()" in C#
let private privateStaticMethod() = ignore()
// OK. Expect: "internal class InternalClass" in C#
type private InternalClass() =
// FAIL. Expect: "private int privateInstanceField" in C#
let privateInstanceField = 0
// FAIL. Expect: "private static int privateStaticField" in C#
static let privateStaticField = 0
// FAIL. Expect: "private int privateInstanceMethod()" in C#
let privateInstanceMethod() = privateInstanceField
// FAIL. Expect: "private in PrivateInstanceMember()" in C#
member private this.PrivateInstanceMember() = privateInstanceField
// OK. Expect: "internal int InternalInstanceMember" in C#
member internal this.InternalInstanceMember() = privateStaticField
He creado un poco de código C # para asegurarme de que no estoy imaginando cosas.
C # código de prueba , y todo compila.
public class TestVisibility
{
// This is a demo to verify that the members are indeed
// internal (assembly) and can be accessed from C# if the
// F# assembly is compiled with [<assembly:InternalsVisibleTo("C# assembly")>]
public void Run()
{
// All of these compile.
PrivateModule.privateStaticMethod();
InternalClass x = new InternalClass();
int a = InternalClass.privateStaticField;
var b = x.InternalInstanceMember();
var c = x.PrivateInstanceMember();
var d = x.privateInstanceField;
var f = x.privateInstanceMethod();
}
}
Utilicé VS2012, apuntando a .NET 4.0, todas las configuraciones son predeterminadas. Intentó ambos modos, Debug y Release, con los mismos resultados.
Pregunta : ¿Cuál es el comportamiento real esperado según el diseño? ¿Es un error? O estoy haciendo algo mal?
Sugerencia : si este es el comportamiento previsto, ¿tal vez sería una buena idea mencionarlo explícitamente en la documentación en alguna parte?
A partir de la especificación F # 3.0 : la forma compilada por CLI de todas las entidades no públicas es interna .