2012-03-05 6 views
11

Ok Derivo un tipo B de una clase base A. A implementa IDisposable explícita, pero tengo que hacer la limpieza adicional en B, por lo que aplicar IDisposable en B:llame a un método de interfaz explícita de clase base en F #

interface IDisposable with 
    member i.Dispose() = 
     // ... additional work 
     base.Dispose() // <- want to do but cannot 

pregunta es: ¿cómo acceder a la Desechar método de la base?

(base :> IDisposable).Dispose() 

produce error del compilador: Unexpected symbol ':>' in expression. Expected '.' or other token.

Hacer algo como

(i :> IDisposable).Dispose() 

, por supuesto, se obtiene un StackOverflowException en tiempo de ejecución - así que ¿cómo puedo hacer esto? Lo siento, pero nunca he encontrado algo como esto antes ...

Respuesta

8

Probablemente sea mejor que pongas tu lógica de limpieza en un método virtual e implementes IDisposable solo una vez.

type A() = 
    abstract Close : unit -> unit 
    default __.Close() = 
    printfn "Cleaning up A" 
    interface System.IDisposable with 
    member this.Dispose() = this.Close() 

type B() = 
    inherit A() 
    override __.Close() = 
    printfn "Cleaning up B" 
    base.Close() 

Como no hay modificador protected acceso, se puede utilizar un archivo de firma para hacer Close no pública (o marcarlo internal).

La palabra clave base solo se puede usar para el acceso de miembros, no de forma independiente. Es por eso que base :> IDisposable no funciona.

Buscando en Reflector, Dispose solo llama al público Close método. De modo que podría volver a implementar IDisposable y llamar al base.Close().

Puede tener este mismo escenario en C#. Las clases heredables que implementan IDisposable deben proporcionar una forma para que las subclases se "enchufen" a la eliminación. Esto generalmente se hace proporcionando una sobrecarga protected virtual Dispose(disposing) que se llama desde Dispose(). Por alguna razón, DuplexClientBase no sigue esta convención. Tal vez se consideró innecesario dado que Dispose meramente lo reenvía a Close.

+0

bien - Me podría haber puesto a mal - A no es uno de mis propios tipos (que es un 'DuplexClientBase') - por lo que esta no es una solución. Y sí sé que no se puede usar la base de esta manera (el compilador dice mucho) - la pregunta es ¿CÓMO llego a la base Dispose of? Por ahora, resolví esto usando un método de miembro público para limpiar y hacer que las personas que llaman limpiaran llamando a este método + eliminar, pero esto es solo un truco y se siente mal – Carsten

+0

¿Has verificado si hay una sobrecarga sobrante de 'Dipose'? 'vacío virtual protegido Dispose (bool disposing)' es un patrón común. – Daniel

+0

No he comprobado explícitamente pero no si MSDN tiene razón: http://msdn.microsoft.com/en-us/library/ms576169.aspx - Tengo la sensación de que no se puede hacer esto en F #, de ser así alguien puede confirmarlo ? – Carsten

5

No puede hacer esto desde C# o cualquier otro idioma; las interfaces explícitas no permiten esto.

+0

gracias por sus comentarios, de hecho, nunca me he metido en esto antes, pero Daniel ya lo mencionó y solo puedo marcar una respuesta, así que * solo * +1 – Carsten

Cuestiones relacionadas