2010-06-10 8 views
7

Tengo una clase no desechable con la sintaxis Abrir/Cerrar que me gustaría poder use, así que estoy tratando de heredar de ella, y trabajo el Open en el new y Close in To Dispose.F # sintaxis del constructor - reemplazar y aumentar el nuevo

La segunda parte está bien, pero no puedo encontrar la manera de hacer el Abierto:

type DisposableOpenCloseClass(openargs) = 
    inherit OpenCloseClass() 
    //do this.Open(openargs) <-- compiler no like 
    interface IDisposable 
     with member this.Dispose() = this.Close() 

(cf. this question que pedí hace mucho tiempo, pero no puedo unir los puntos a éste)

Respuesta

10

Key es as this:

type OpenCloseClass() = 
    member this.Open(x) = printfn "opened %d" x 
    member this.Close() = printfn "closed" 

open System 

type DisposableOpenCloseClass(openargs) as this = 
    inherit OpenCloseClass() 
    do this.Open(openargs) 
    interface IDisposable 
     with member this.Dispose() = this.Close() 

let f() = 
    use docc = new DisposableOpenCloseClass(42) 
    printfn "inside" 

f() 
4

Como Brian sugiere, se puede utilizar la cláusula as this. Sin embargo, en F #, generalmente se recomienda utilizar subclases (herencia) solo cuando hay una buena razón para eso (por ejemplo, debe implementar alguna clase virtual y pasarla a una biblioteca .NET).

Si yo estaba poniendo en práctica su ejemplo, me gustaría probablemente preferiría función que devuelve IDisposable usando un simple expresión objeto:

let disposableOpenClose(openargs) = 
    let oc = new OpenCloseClass() 
    oc.Open(openargs) 
    { new IDisposable with 
     member this.Dispose() = oc.Close() } 

let f() = 
    use docc = disposableOpenClose(42) 
    printfn "inside" 

Hasta cierto punto, esto es sólo una preferencia personal, pero creo que es una opción preferida, porque es más simple que usar herencia (aunque no tengo ningún documento para vincular aquí :-)). Además, el código compilado puede ser un poco más simple, porque el manejo de as this puede requerir algunas verificaciones de tiempo de ejecución.

+0

Gracias, en mi caso particular, necesitaba acceso a otras funciones en la clase 'base', por lo que solo devolver la interfaz no sería suficiente. – Benjol

Cuestiones relacionadas