Implémentation de GetEnumerator () pour une collection héritée de List & lt; string & gt;
Je suis en train de mettre en œuvre FilePathCollection
. Ses articles les simples noms de fichier (sans chemin d'accès, comme "image.jpg"). Une fois la collecte est utilisé par foreach
cycle, il devrait reprendre le chemin d'accès complet créé par la concaténation avec baseDirectory
. Comment puis-je le faire?
public class FilePathCollection : List<string>
{
string baseDirectory;
public FilePathCollection(string baseDirectory)
{
this.baseDirectory = baseDirectory;
}
new public System.Collections.IEnumerator GetEnumerator()
{
foreach (string value in this._items) //this does not work because _list is private
yield return baseDirectory + value;
}
}
source d'informationauteur Vojtech
Vous devez vous connecter pour publier un commentaire.
Si vous avez le C# 3, vous n'avez pas besoin d'écrire une classe spéciale pour le faire. En supposant que vous avez une séquence de chaînes de caractères, comme un
List<string>
oustring[]
quelque chose qui prend en chargeIEnumerable<string>
appeléfilePathCollection
vous pouvez simplement utiliser:Hey presto - vous avez maintenant un
IEnumerable<string>
des chemins avec le préfixebaseDirectory
de sorte que vous pouvez utiliserforeach
sur elle, etc. Nous avons terminé.Le reste de cette réponse est plus général d'explication pour vous aider (et autres) à l'endroit où cela peut être appliqué dans d'autres cas.
Select
signifie essentiellement: prenez cette séquence d'éléments, de faire quelque chose avec chaque élément et de me donner en retour une nouvelle séquence contenant tous les résultats. Le "quelque chose" est spécifiée en fournissant une méthode qui accepte un paramètre du même type que ceux stockés dans l'ancienne séquence et retourne le type que vous aimez, qui sera le type d'élément de la nouvelle séquence. Dans ce cas, nous ne sommes pas changer le type d'élément. Aussi nous sommes à la définition de la méthode "en place" à l'aide d'un lambda:Le compilateur chiffres que le type de l'élément de la collection source
string
doncpath
est unstring
- vous pouvez penserpath
que de jouer le même rôle qu'une "variable de boucle" si vous aviez à écrire l'ensemble de la chose par vous-même. Et surpath
nous utiliser la concaténation, de sorte que le résultat en est une autrestring
de sorte que la nouvelle séquence doit également êtreIEnumerable<string>
. C'est "l'inférence de type" et est une partie importante de la façon dont ce genre de choses qui réduit la quantité de code à écrire.L'autre chose importante qui se passe est la "fermeture", qui est le nom technique pour la façon dont nous faisons nos lambda ne dépendent pas seulement de son "ouvrir" paramètre
path
mais aussi sur un "fermé" paramètrebaseDirectory
qui n'est même pas explicitement transmis en tant que paramètre. Un lambda peut juste arriver en dehors de lui-même et d'apprendre à les variables visibles de la méthode qu'elle est définie à l'intérieur. C'est précisément ce qui vous libère de la nécessité d'écrire un constructeur qui prendbaseDirectory
en tant que paramètre et la stocke dans un_baseDirectory
le terrain de sorte que vous pouvez l'utiliser par la suite à plusieurs reprises dans une autre méthode.Remarque que la nouvelle séquence est toujours la même longueur que les entrants de la séquence. Si vous souhaitez filtrer des éléments, utilisez
Where
. Si vous voulez faire une séquence de plus, l'utilisationSelectMany
.en utilisant le nouveau mot-clé qui peut vous causer de polymorphisme de problèmes:
dans le cas où certains n':
appel
foreach (var files in files)
sera la cause d'appel l'a pas remplacé l'énumérateur.Je pense que le mieux est d'hériter de
IEnumerable<string>
et maintenez un domaine privé avec votre Liste.Par exemple, cela pourrait être une façon de le faire: l'héritage de je
List<string>
laquelle il a déjà hériter deIEnumerable<T>
Vous pourriez probablement utiliser la base.GetEnumerator() et manuellement itérer sur que.
Cependant, je pense que vous avez va courir à toutes sortes de problèmes de la conception de la classe de la façon dont vous êtes en train de le faire. Vous devriez obtenir les mêmes valeurs d'une liste que vous mettez dans. Par exemple, avec le code que vous montrez que vous obtenez différentes valeurs de l'énumération de la liste que lors de l'utilisation de l'indexeur. Aussi, serait-il être clair ce que d'autres méthodes de Liste de tâches telles que la méthode Add() ou()?
Est-il une raison pour laquelle vous ne pouvez pas il suffit de créer une méthode statique qui prend un nom de fichier de la liste et d'un répertoire de base, puis crée une nouvelle liste où chaque élément est dir+fichier?
Vous pourriez jeter à type de base.
Idéalement, je voudrais juste utiliser le
Select
méthode d'extension. Et de lui donner une surcharge générique s'il vous plaît...