リスト内の最大の項目を見つけるためだけに全体の並べ替えを行うのは、非常に非効率的です。
Jon Skeet などの MoreLinq など、「MaxBy()」Linq 拡張機能のいずれかを使用して最大値を見つけることをお勧めします。(完全なライブラリはここにあります。)
コードを使用するMaxBy()
と、次のようになります。
public static FileInfo GetNewestFile(DirectoryInfo directory)
{
return directory.GetFiles()
.Union(directory.GetDirectories().Select(d => GetNewestFile(d)))
.MaxBy(f => (f == null ? DateTime.MinValue : f.LastWriteTime));
}
理想的には、これを他の提案された回答と組み合わせます (つまりDirectory.EnumerateFiles()
、再帰を行うオーバーロードを使用します)。
完全なコンソール アプリのサンプルを次に示します。「MaxBy()」メソッドは、古いバージョンの MoreLinq から取得され、多少変更されています。
using System;
using System.Collections.Generic;
using System.IO;
namespace Demo
{
public static class Program
{
private static void Main()
{
string root = "D:\\Test"; // Put your test root here.
var di = new DirectoryInfo(root);
var newest = GetNewestFile(di);
Console.WriteLine("Newest file = {0}, last written on {1}", newest.FullName, newest.LastWriteTime);
}
public static FileInfo GetNewestFile(DirectoryInfo directory)
{
return directory.EnumerateFiles("*.*", SearchOption.AllDirectories)
.MaxBy(f => (f == null ? DateTime.MinValue : f.LastWriteTime));
}
}
public static class EnumerableMaxMinExt
{
public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
{
return source.MaxBy(selector, Comparer<TKey>.Default);
}
public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector, IComparer<TKey> comparer)
{
using (IEnumerator<TSource> sourceIterator = source.GetEnumerator())
{
if (!sourceIterator.MoveNext())
{
throw new InvalidOperationException("Sequence was empty");
}
TSource max = sourceIterator.Current;
TKey maxKey = selector(max);
while (sourceIterator.MoveNext())
{
TSource candidate = sourceIterator.Current;
TKey candidateProjected = selector(candidate);
if (comparer.Compare(candidateProjected, maxKey) > 0)
{
max = candidate;
maxKey = candidateProjected;
}
}
return max;
}
}
}
}