2010-11-27 6 views
3

Je suis un peu confus sur le concept des méthodes retournant des interfaces. Y at-il un article ou une référence qui en discute en détail? Je suis confus sur quand/pourquoi vous pourriez vouloir faire ceci, et comment est-ce que vous pouvez lancer une interface vers/à partir de l'objet auquel il est associé (je pense que c'est vrai).C# - Méthodes qui retournent des interfaces

+1

Je vous ai fait une interface, mais je Casted ça ...;) –

Répondre

14

Je suis confus quand/pourquoi vous pouvez faire cela,

De retour d'une interface est bien quand vous voulez séparer le contrat de ce que quelque chose est censé faire, du béton mise en œuvre (comment ça marche). Avoir une interface vous permet de réutiliser et de modifier le code plus facilement.

Si vous avez une interface IFoo et une implémentation SimpleFoo qui implémente naïvement IFoo vous pouvez programmer contre l'interface et obtenir des fonctionnalités de base. Plus tard, vous pouvez effectuer une implémentation AdvancedFoo qui implémente également la même interface IFoo. Il vous suffit maintenant de renvoyer votre nouvel objet et le reste du code utilisera la nouvelle classe plus avancée sans nécessiter de modifications. Avoir l'interface vous permet également de choisir la classe à utiliser lors de l'exécution. Lorsque votre code renvoie des interfaces, il est également plus flexible. Vous pouvez actuellement retourner un List<T> mais si le résultat ne doit être utilisé que comme IEnumerable<T>, vous devriez le retourner à la place. Vous pouvez ensuite modifier votre implémentation pour que les résultats soient générés à la volée (par exemple avec un bloc d'itérateur) et que le code appelant fonctionne toujours.

comment est-ce que vous pouvez lancer une interface/de l'objet auquel il est associé

Le point d'interfaces tout est que vous ne devriez pas avoir à le faire. Vous devriez simplement utiliser l'interface sans vous soucier de l'implémentation spécifique. La méthode correcte sera appelée par le runtime. Si vous pensez que vous avez besoin de le diffuser, cela peut indiquer que votre interface n'est pas assez riche pour répondre à vos besoins.

Vous pouvez lancer si vous devez bien:

IFoo foo = getFoo(); 
SimpleFoo simpleFoo = (SimpleFoo)foo; 

Notez que cette distribution peut échouer et vous pouvez utiliser as à la place:

IFoo foo = getFoo(); 
SimpleFoo simpleFoo = foo as SimpleFoo; 
if (simpleFoo == null) 
{ 
    // Too bad... 
} 
else 
{ 
    // Now we can use simpleFoo. 
} 
+0

Voici un exemple de la façon dont je l'ai vu des interfaces retournées. Dans notre application, nous avons un client qui récupère des données de notre serveur via Wcf. Au lieu d'avoir différentes méthodes 'Get' pour chaque type d'entité, nous avons une méthode Get qui retourne une interface. L'interface contient une propriété qui indique le type de l'entité. En fonction du type, l'interface (objet) est castée au type approprié et utilisée. – Hosea146

+0

@ Hosea146: 'object' n'est pas une interface - c'est une classe. Je ne suis pas exactement sûr de ce que le code est dans le code que vous avez, mais cela ne semble pas être un bon exemple d'utilisation d'interfaces - si c'est en fait en utilisant des interfaces. –

+0

Je vais poster une autre question à ce sujet pour mieux illustrer ce que nous faisons. – Hosea146

0

Je ne sais pas ce qui est source de confusion au sujet il. Une interface est fondamentalement équivalente à une classe abstraite qui n'a pas de méthodes non abstraites et aucun état déclaré (champs). Le retour d'une interface revient à retourner une classe de base abstraite.

La raison pour laquelle vous souhaitez renvoyer une interface à la place est que les interfaces représentent des petits groupes de fonctionnalités plutôt que des objets complets. Un exemple classique renvoie IEnumerable au lieu de List car même si l'objet sous-jacent peut être une liste, la méthode renvoie simplement un ensemble ordonné d'objets et c'est tout ce que l'appelant devrait voir. À l'avenir, la méthode peut renvoyer un tableau ou une autre structure de données. Mais cela n'aura aucune importance pour l'appelant car tout l'appelant voit IEnumerable. Ceci suit le principe général de programmation aux interfaces au lieu des implémentations.

0

Les méthodes ne peuvent pas renvoyer une interface elle-même. Une interface est une description des méthodes qu'un objet doit implémenter. Vous ne pouvez pas renvoyer une liste de méthodes qu'un objet doit avoir.

Ce que vous pouvez faire est de renvoyer une instance d'une interface. Prenez le code qui ressemble à ceci:

using System.Collections.Generic; 

ICollection<int> getCollection() { 
    return new LinkedList<int>(); 
} 

Cette méthode renvoie une instance de LinkedList, mais son type de retour est ICollection. Cela signifie que vous pouvez utiliser la valeur de retour de getCollection() partout où vous pouvez utiliser une ICollection puisque LinkedList hérite de ICollection. Si le type de retour était LinkedList, vous ne pouviez utiliser que le type de retour où une LinkedList était attendue, ce qui réduit votre flexibilité.

C# interfaces tutorial

1

Parfois, vous voulez retourner une interface parce qu'il est d'une manière générale de retourner une classe qui implémente. Vous n'aurez pas à vous soucier de la classe renvoyée car vous pourrez appeler les méthodes présentes dans l'interface.

Par exemple:

public interface IFooBar 
{ 
    String GetData(); 
} 

public class Foo : IFooBar 
{ 
    public String GetData() { return "Foo"; } 
} 

public class Bar : IFooBar 
{ 
    public String GetData() { return "Bar"; } 
} 

public class DataManager 
{ 
    public static IFooBar GetFooBar() 
    { 
     IFooBar foobar = ... 
     return foobar; 
    } 
} 

public class MainAppClass 
{ 
    public void SomeMethod() 
    { 
     //You don't care what type of class you get here 
     //you only care that the object you get back let's you 
     //call GetData. 
     IFooBar foobar = DataManager.GetFooBar(); 
     String data = foobar.GetData(); 
     //etc 
    } 
} 
Questions connexes