15 votes

appeler une méthode d'interface explicite de classe de base en F#

Ok, je dérive un type B à partir d'une classe de base A . A met en œuvre IDisposable explicite mais je dois faire un nettoyage supplémentaire dans B donc je mets en œuvre IDisposable sur B :

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

La question est : comment accéder à la méthode Dispose depuis la base ?

(base :> IDisposable).Dispose()

produit une erreur de compilation : Unexpected symbol ':>' in expression. Expected '.' or other token.

Faire quelque chose comme

(i :> IDisposable).Dispose()

donne bien sûr un StackOverflowException au moment de l'exécution - alors comment puis-je faire cela ? Désolé, mais je n'ai jamais rencontré quelque chose comme ça auparavant...

10voto

Daniel Points 29764

Il est probablement préférable de placer votre logique de nettoyage dans une méthode virtuelle et d'implémenter IDisposable une seule fois.

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()

Puisqu'il n'y a pas protected modificateur d'accès, vous pouvez utiliser un fichier de signature pour rendre Close non public (ou le marquer internal ).

El base Le mot-clé ne peut être utilisé que pour l'accès des membres, pas de façon autonome. C'est pourquoi base :> IDisposable ne fonctionne pas.

Regarder dans Reflector, Dispose n'appelle que le public Close méthode. Vous pourriez donc réimplémenter IDisposable et appeler base.Close() à la place.

Vous pourriez avoir ce même scénario en C#. Les classes héritables qui implémentent IDisposable doit fournir un moyen pour les sous-classes de se "brancher" sur l'élimination. Cela se fait généralement en fournissant un protected virtual Dispose(disposing) qui est appelée par Dispose() . Pour quelque raison que ce soit, DuplexClientBase ne suit pas cette convention. Peut-être que cela a été jugé inutile étant donné que Dispose se contente de transmettre à Close .

5voto

Brian Points 82719

Vous ne pouvez pas faire cela à partir de C# ou de tout autre langage ; les interfaces explicites ne le permettent pas.

0voto

Roland Pihlakas Points 583

L'appel d'une interface explicite de la classe de base peut être fait en utilisant la réflexion.
Voir ma réponse à une question connexe sur le C# :
Comment appeler une méthode d'interface explicitement implémentée dans la classe de base ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X