MODIFIER:
Des réponses données, il m'est plutôt clair comment la conception que je demande ci-dessous devrait en fait être implémentée. Avec ces suggestions à l'esprit (et en réponse à un commentaire indiquant poliment que mon code exemple ne compile même pas), j'ai modifié le code suivant pour refléter ce que semble être le consensus général. La question qui reste peut ne plus avoir de sens à la lumière du code, mais je la laisse telle quelle pour la postérité.
Supposons que j'ai trois surcharges d'une fonction, une prenant IEnumerable
, une prenant ICollection
, et une prenant IList
, quelque chose comme ce qui suit:
public static T GetMiddle(IEnumerable values) {
IList list = values as IList;
if (list != null) return GetMiddle(list);
int count = GetCount(values);
T middle = default(T);
int index = 0;
foreach (T value in values) {
if (index++ >= count / 2) {
middle = value;
break;
}
}
return middle;
}
private static T GetMiddle(IList values) {
int middleIndex = values.Count / 2;
return values[middleIndex];
}
private static int GetCount(IEnumerable values) {
// si les valeurs sont en fait une ICollection (par exemple, List),
// nous pouvons obtenir le nombre assez bon marché
ICollection genericCollection = values as ICollection;
if (genericCollection != null) return genericCollection.Count;
// même pour ICollection (par exemple, Queue, Stack)
ICollection collection = values as ICollection;
if (collection != null) return collection.Count;
// sinon, nous devons compter les valeurs nous-mêmes
int count = 0;
foreach (T value in values) count++;
return count;
}
L'idée ici est que, si j'ai un IList
, cela facilite mon travail; d'autre part, je peux toujours faire le travail avec un ICollection
ou même un IEnumerable
; l'implémentation pour ces interfaces n'est tout simplement pas aussi efficace.
Je n'étais pas sûr que cela fonctionnerait même (si le runtime serait capable de choisir une surcharge basée sur le paramètre passé), mais je l'ai testé et il semble que oui.
Ma question est : y a-t-il un problème avec cette approche auquel je n'ai pas pensé ? Alternativement, cette approche est-elle en fait bonne, mais y a-t-il une meilleure façon de l'accomplir (peut-être en essayant de caster l'argument values
en un IList
d'abord et en exécutant la surcharge plus efficace si le cast fonctionne) ? Je suis juste intéressé à savoir ce que les autres pensent.