Да, иногда. Проблема, которую я вижу, состоит в том, что много людей, хотя они знают их, они не знают, как действительно применить их. Большинство людей возвращается назад к связанным спискам массивов и т.д. Они сделают задание в большинстве случаев как более усовершенствованную структуру данных (иногда, действительно необходимо "ударить его" в место), они просто менее эффективны. Люди склонны делать то, что легче для них, но это - не обязательно лучший способ сделать что-то. Я не могу дать сбой их, я уверен, что делаю это также, но именно поэтому Вы не видите много "усовершенствованных" понятий в программировании.
На основании ответа Струдсо, но в качестве методов расширения для FileInfo
и DirectoryInfo
.
public static IEnumerable<FileInfo> EnumerateFilesSafe(this DirectoryInfo dir, string filter = "*.*", SearchOption opt = SearchOption.TopDirectoryOnly)
{
var retval = Enumerable.Empty<FileInfo>();
try { retval = dir.EnumerateFiles(filter); }
catch { Debug.WriteLine("{0} Inaccessable.", dir.FullName); }
if (opt == SearchOption.AllDirectories)
retval = retval.Concat(dir.EnumerateDirectoriesSafe(opt: opt).SelectMany(x => x.EnumerateFilesSafe(filter, opt)));
return retval;
}
public static IEnumerable<DirectoryInfo> EnumerateDirectoriesSafe(this DirectoryInfo dir, string filter = "*.*", SearchOption opt = SearchOption.TopDirectoryOnly)
{
var retval = Enumerable.Empty<DirectoryInfo>();
try { retval = dir.EnumerateDirectories(filter); }
catch { Debug.WriteLine("{0} Inaccessable.", dir.FullName); }
if (opt == SearchOption.AllDirectories)
retval = retval.Concat(retval.SelectMany(x => x.EnumerateDirectoriesSafe(filter, opt)));
return retval;
}
MoveNext
вызывает исключение.
Я пытался написать метод, который обходит последовательность и пытается игнорировать MoveNext
исключения. Однако я не уверен, что MoveNext
продвигает позицию, когда генерирует исключение, так что это также может быть бесконечный цикл. Это также плохая идея, потому что мы будем полагаться на детали реализации.
Но это просто так весело!
public static IEnumerable<T> SafeWalk<T> (this IEnumerable<T> source)
{
var enumerator = source.GetEnumerator();
bool? hasCurrent = null;
do {
try {
hasCurrent = enumerator.MoveNext();
} catch {
hasCurrent = null; // we're not sure
}
if (hasCurrent ?? false) // if not sure, do not return value
yield return enumerator.Current;
} while (hasCurrent ?? true); // if not sure, continue walking
}
foreach (var file in Directory.EnumerateFiles("c:\\", "*", SearchOption.AllDirectories)
.SafeWalk())
{
// ...
}
Это будет работать только в том случае, если следующие условия верны для реализации каркаса этого итератора (см. FileSystemEnumerableIterator<TSource>
в Reflector для справки ):
MoveNext
продвигает свою позицию, когда он терпит неудачу; MoveNext
терпит неудачу на последнем элементе, последующие вызовы возвратят false
вместо того, чтобы вызвать исключение; Даже если это работает, пожалуйста, никогда не используйте его в производстве!
Но мне действительно интересно, если это работает.