Les réponses à des questions de ce genre: List<T> ou IList<T> toujours semblent d'accord pour dire que le retour d'une interface est mieux que de retourner une mise en œuvre concrète d'une collection. Mais j'ai du mal avec cette. L'instanciation d'une interface est impossible, donc si votre méthode est de retour en une interface, et bien c'est encore de retour d'une mise en œuvre spécifique. J'ai essayé un peu avec cela par écrit 2 petites méthodes:
public static IList<int> ExposeArrayIList()
{
return new[] { 1, 2, 3 };
}
public static IList<int> ExposeListIList()
{
return new List<int> { 1, 2, 3 };
}
Et de les utiliser dans mon programme de test:
static void Main(string[] args)
{
IList<int> arrayIList = ExposeArrayIList();
IList<int> listIList = ExposeListIList();
//Will give a runtime error
arrayIList.Add(10);
//Runs perfectly
listIList.Add(10);
}
Dans les deux cas, lorsque j'essaie d'ajouter une nouvelle valeur, mon compilateur me donne pas d'erreur, mais, évidemment, la méthode qui expose mon tableau en tant qu' IList<T>
donne une erreur d'exécution lorsque j'essaie d'ajouter quelque chose à cela.
Donc, les gens qui ne savent pas ce qui se passe dans ma méthode, et ont pour ajouter des valeurs, sont obligés de la première copie de mon IList
d'un List
à être en mesure d'ajouter des valeurs sans risquer des erreurs. Bien sûr, ils peuvent faire un typecheck pour voir si ils sont traiter avec un List
ou Array
, mais si ils ne le font pas, et ils veulent ajouter des éléments à la collection qu'ils ont pas d'autre choix que de copier l' IList
d'un List
, même si elle ne l'est déjà un List
. Si un tableau ne jamais être exposés en IList
?
Une autre source de préoccupation est fondée sur la a accepté la réponse de la question liée (l'emphase est mienne):
Si vous êtes exposant votre classe grâce à une bibliothèque que d'autres l'utilisent, en général, vous souhaitez exposer via des interfaces plutôt que des implémentations concrètes. Cela aidera si vous décidez de changer la mise en œuvre de votre classe, plus tard, pour utiliser une autre classe de béton. Dans ce cas, les utilisateurs de votre bibliothèque n'aurez pas besoin de mettre à jour leur code depuis l'interface ne change pas.
Si vous êtes juste en utilisant en interne, vous ne se soucient pas tellement, et en utilisant la Liste peut être ok.
Imaginez quelqu'un réellement utilisé mon IList<T>
qu'ils ont obtenu de mon ExposeListIlist()
méthode juste comme ça pour ajouter/supprimer des valeurs. Tout fonctionne très bien. Mais maintenant, comme la réponse suggère, parce que le renvoi d'une interface est plus flexible que je retourne un tableau au lieu d'une Liste (pas de problème de mon côté!), alors ils sont un régal...
TLDR:
1) Exposer une interface causes inutiles jette? N'est-ce pas important?
2) Parfois, si les utilisateurs de la bibliothèque ne pas utiliser un cast, leur code peut briser lorsque vous changez votre méthode, même si la méthode reste tout à fait correct.
Je suis probablement avoir à y penser, mais je n'ai pas le consensus général que la restitution d'une interface est préférable à un retour de mise en œuvre.