2010-12-02 10 views
9

Supongamos que tengo un par de clases, obviamente artificiales C# como esto:Cómo sellar una propiedad anulado

public abstract class Foo { 
    public abstract int[] LegalValues { get; } 
    public virtual bool IsValueLegal(int val) { 
     return Array.IndexOf(LegalValues, val) >= 0; 
    } 
} 

y esto:

¿Cómo puedo hacer esto en C#? El código obvio para las propiedades:

[<Sealed>] 
override this.LegalValues with get() = // ... 

[<Sealed>] 
override this.IsValueLegal value = // ... 

Desencadena un error porque el atributo SealedAttribute aparentemente no se puede aplicar a los miembros. Puedo, por supuesto, sellar toda la clase y sellar así todos los miembros, pero (y este es un realmente importante pero) es que tengo el objetivo de emparejar una firma de clase existente exactamente y la clase base tiene otra miembros virtuales/abstractos que deberían, idealmente, seguir siendo invalidables.

+1

¡Hm, ni siquiera sabía que era posible sellar métodos individuales en C#/CLR! – Brian

Respuesta

3

Actualmente hay varias limitaciones para el soporte de F # para OO, por lo que generalmente no debe esperar poder generar una jerarquía de clase F # que sea idéntica a una jerarquía de clase C# arbitraria. Hasta donde yo sé, no hay forma de anular y sellar un método virtual.

5

Parece que F # define que Sealed Attribute se define con su propiedad AttributeTargets establecida en Clase solamente, probablemente no sea posible sellar miembros.

Esto es probablemente ok, ya que las funciones de herencia y anulación generalmente son menos idiomáticas en F # que en C#. No creo que realmente pueda obtener lo que quiere sin volver a escribir en más modismos F #. Comenzar con esto:

type foo = 
    | Bar 
    | Baz 
    | Qux 
     with 
      member this.LegalValues = 
       match this with 
       | Bar -> [0; 1] 
       | Qux -> [-1; 0; 1] 
       | Baz -> [0 .. 10 ] 
      member this.IsValueLegal value = 
       match this with 
       | Baz -> value >= 0 && value <= 10 
       | _ -> List.exists (fun x -> x = value) (this.LegalValues) 

Se puede decir que Baz "anula" el Miembro foo.IsValueLegal, todos los otros tipos utilizan la función "base".

+0

Enfoque interesante, pero no puedo usarlo: la clase base define una herencia particular, por lo que no puedo redefinir Foo bajo ninguna circunstancia y se me requiere en Bar para evitar que alguien anule estos métodos. Si tengo que sellar toda la clase, que así sea. Si bien esto cortará ciertas operaciones, podrían simularse de otras maneras (adaptadores, etc.). – plinth

Cuestiones relacionadas