2009-09-24 9 views
0

Imaginer le code suivant:Comment approcher une classe qui implémente une interface et a une classe de base?

MyService myService = new MyService(); 
myService.Start(); 
myService.DoStuff(); 

La classe MyService ressemble à ceci:

public class MyService : ClientBase, IMyService 
{ 
... 
} 

Maintenant, je voulais changer le code existant pour appeler cette classe en utilisant son interface:

IMyService myService = GetMyService(); 
myService.Start(); 
myService.DoStuff(); 

Regarde mieux, mais maintenant j'obtiens une erreur sur la ligne contenant myService.Start();, puisqu'il s'agit d'une implémentation héritée de la classe de base ClientBase.

Que dois-je faire maintenant? Prolonger l'interface IMyService et inclure l'interface ? C'est la seule solution à laquelle je puisse penser maintenant, mais je ne pense pas que ce soit très élégant ...

EDIT: La classe ClientBase est celle de System.ServiceModel donc je ne peux rien changer à ce sujet.

Répondre

1

Il n'y a rien de mal avec l'héritage d'interface ...

public class ClientBase: IClientBase 
{ 
    public ClientBase() 
    { 
    } 

    public void Start() 
    { 
    } 
} 

public interface IClientBase 
{ 
    void Start(); 
} 

... 

public class MyService: ClientBase, IClientBase, IMyService 
{ 
    public MyService() 
    { 
    } 

    public void DoStuff() 
    { 
    } 
} 

public interface IMyService: IClientBase 
{ 
    void DoStuff(); 
} 

Ensuite, vous devriez être autorisé à utiliser votre code existant:

IMyService service = new MyService(); 
service.Start(); 
service.DoStuff(); 

Une autre solution serait de rendre votre classe MyService mettre en œuvre IClientBase puis juste faire un casting:

MyService service = new MyService(); 
(service as IClientBase).Start(); 
(service as IMyService).DoStuff(); 

Cependant, je pense y Nous sommes d'accord, la première solution est beaucoup mieux.

+0

La classe ClientBase est celle de System.ServiceModel et n'a pas d'interface, donc ce n'est pas une option pour moi je pense. Merci quand même. –

+0

Vous avez mentionné dans votre OP qu'il le fait * "Que dois-je faire maintenant? Étendre l'interface IMyService et inclure l'interface ClientBase" * – James

+0

Il y a une autre classe entre les deux, donc votre première réponse était la bonne. J'ai roulé votre édition en arrière, merci. –

2

Si la méthode Start est spécifique à la classe MyService, et ne définit pas l'interface IMyService, vous ne devriez pas appellerez Start sur une référence IMyService ...

D'autre part, si tous IMyService les mises en œuvre devraient soutenir la méthode Start, alors il devrait être défini dans l'interface

Vous pourriez avoir quelque chose comme ça:

interface IMyService 
{ 
    void DoStuff(); 
    void Start(); 
} 

abstract class ClientBase 
{ 
    public void Start() { ... } 
} 

class MyService : ClientBase, IMyService 
{ 
    public void DoStuff() { ... } 
} 
+0

Bien que le code appelant repose sur la méthode Start, mais bien sûr, il ne sait pas que c'est la méthode de la classe de base au lieu d'une méthode sur l'interface. Et actuellement, il n'y a qu'une seule implémentation de l'interface ... Je veux juste en faire une nouvelle pour les tests unitaires (créer un stub). –

0

S'il est nécessaire d'utiliser une méthode de démarrage en tant qu'objet IMyService, il est logique de la placer dans l'interface. Sinon, un réexamen général de votre conception pourrait être en ordre.

+0

Je n'ai pas fait la conception de ceci, mais bien sûr je peux le changer :) –

0

Quelle est l'erreur que vous obtenez?

Vous ne devez pas étendre IMyService pour inclure l'interface ClientBase. J'ai eu des classes de base qui ont implémenté des méthodes d'interface.

Je vérifierais que la méthode Start sur la classe ClientBase est publique, ce qui est requis par toutes les interfaces.

0

Que diriez-vous d'agréger la classe de base et l'implémentation de l'interface dans une classe abstraite à partir de laquelle MyService héritera. Instancier MyService mais laissez la classe abstraite être le point d'entrée.Vous coderiez plutôt vers une classe que vers une interface, mais je ne sais pas comment vous pouvez utiliser une interface puisque vous avez une implémentation concrète à apporter.

Questions connexes