Je travaille sur une méthode pour trouver un chemin de fichier de configuration. Cela doit faire deux passes: d'abord trouver tous les fichiers de configuration existants, puis revenir en arrière et trouver le premier chemin accessible en écriture.Est-il possible de mettre en cache des résultats d'évaluation IEnumerable paresseux?
Bien qu'exhaustif pour ma situation particulière, cela m'a fait réfléchir: est-il possible d'avoir à la fois une évaluation paresseuse et d'éviter l'énumération multiple?
Pour illustrer ce que je veux dire, considérez le code suivant:
public IEnumerable<string> GetPaths()
{
Console.WriteLine("GetPaths() Returning 'one'");
yield return "one";
Console.WriteLine("GetPaths() Returning 'two'");
yield return "two";
Console.WriteLine("GetPaths() Returning 'three'");
yield return "three";
}
public bool IsWritable(string path) => false; // testing only
Si je lance:
var paths = GetPaths();
Console.WriteLine("Searching for existing file..");
foreach (var path in paths)
{
if (File.Exists(path))
{
Console.WriteLine($"Found existing file '{path}'");
}
}
Console.WriteLine("Searching for a writable path..");
foreach (var path in paths.Reverse()) // NOTE: paths enumarated twice
{
if (IsWritable(path))
{
Console.WriteLine($"Found writable path '{path}'");
}
}
Console.WriteLine("No paths found");
Si le fichier 'un' existe, nous obtenons:
Searching for existing file..
Returning 'one'
Found existing file 'one'
Si, cependant, aucun fichier n'existe, nous obtenons:
Searching for existing file..
Returning 'one'
Returning 'two'
Returning 'three'
Searching for a writable path..
Returning 'one'
Returning 'two'
Returning 'three'
No paths found
(nous énumérons gaspillée les résultats de GetPaths() deux fois)
Une solution simple est de changer la première ligne à:
var paths = GetPaths().ToList();
Cependant, cela signifie que même si le fichier one
existe, la sortie serait:
Returning 'one'
Returning 'two'
Returning 'three'
Searching for existing file..
Found existing file 'one'
(comme, nous énumérons inutilement la r emainder de la liste)
est-il un (moyen intégré) pour obtenir à la fois l'énumération paresseux et toujours empêcher l'énumération multiple?
En d'autres termes, la sortie désirée lorsque 'un' existe est:
Searching for existing file..
Returning 'one'
Found existing file 'one'
et si aucun fichier existe:
Searching for existing file..
Returning 'one'
Returning 'two'
Returning 'three'
Searching for a writable path..
No paths found
Oui. Appelez 'ToArray' sur l'énumérable. – Will
Je ne crois pas qu'il y ait quelque chose de intégré pour ça, non. Vous pourriez l'appliquer vous-même, mais c'est une question différente. –
@Will: En quoi est-ce encore paresseux? Cela équivaut (en termes d'évaluation) à appeler 'ToList()' que l'OP a déjà expliqué ... –