2010-03-05 15 views

Respuesta

33

El modificador protected puede ser bastante problemático en F #, porque a menudo es necesario llamar a miembros desde una expresión lambda. Sin embargo, cuando haces eso, ya no tienes acceso al método desde dentro de la clase. Esto también causa confusión cuando se usan miembros protegidos declarados en C# (consulte, por ejemplo, this SO question). Si usted podría declarar un miembro de protected, el siguiente código podría ser sorprendente:

type Base() = 
    protected member x.Test(a) = a > 10 

type Inherited() = 
    inherit Base() 
    member x.Filter(list) = 
    list |> List.filter (fun a -> x.Test(a)) 

Este código no funcionaría, ya que está llamando Test de una función lambda (que es un objeto diferente de la instancia actual de Test), por lo que el código no funcionaría. Creo que esta es la razón principal para no apoyar el modificador protected en F #.

En F # normalmente utiliza la herencia de implementación (es decir, hereda de una clase base) con mucha menos frecuencia que en C#, por lo que no debería necesitar protected con tanta frecuencia. En cambio, generalmente se prefiere usar interfaces (en el código F # orientado a objetos) y funciones de orden superior (en el código funcional). Sin embargo, es difícil decir cómo evitar la necesidad de protected en general (aparte de evitar la herencia de implementación). ¿Tiene algún ejemplo específico que motivó su pregunta?

+26

Esto es cierto, pero es un artefacto de implementación del compilador. No existe una razón fundamental para que un lenguaje .NET similar a F # no pueda generar una clase anidada para albergar el cierre y tener la semántica deseada. – kvb

+0

Buena explicación. Es fácil olvidarse de los objetos que el compilador F # crea para admitir lambdas y otras construcciones funcionales. Estoy escribiendo un ORM que se usará frecuentemente desde C#. Utiliza algo de un modelo de proveedor. Hay una clase abstracta de Repository, que podría ser ampliada por SqlRepository, OracleRepository, etc. Quería un método protegido que cargue información de esquema para una tabla. ¿Alguna idea de una mejor manera de hacer esto? – Daniel

+0

@kvb - Pensé lo mismo. ¿Hay alguna manera en que el compilador pueda verificar si se accede a un miembro protegido desde un lambda en una clase derivada? – Daniel

7

En cuanto a si F # permite una mejor forma de modelado de datos, los archivos de firma permiten tomar decisiones de visibilidad más detalladas que internal en C#, que a menudo es muy agradable. Vea el comentario de Brian here para una explicación un poco más. Esto es independiente de la compatibilidad (o la falta de ella) para protected, sin embargo.

+0

enlace parece muerto – Maslow

+0

@Maslow - Gracias por señalar esto; Actualicé el enlace a lo que creo que es un espejo de la publicación original. – kvb

Cuestiones relacionadas