LINQでファイルが存在するかどうかチェックする


C#でLINQを使ってファイルが存在するかどうかをチェックします。環境変数のPATHおよびPATHEXTの内容を考慮します。

※ 2015/03/19頂いたアドバイスを元に改良しました。

コード
var path = "探したいファイル";
var found = Environment.GetEnvironmentVariable("PATH").Split(';')
  .Select(x => Path.Combine(x, path))
  .SelectMany(_ => Environment.GetEnvironmentVariable("PATHEXT").Split(';')
    .Concat(new String[] { Path.GetExtension(path) }), 
      (p, ext) => Path.ChangeExtension(p, ext))
  .Any(File.Exists);
使用例
var path = "perl";
var found = Environment.GetEnvironmentVariable("PATH").Split(';')
  .Select(x => Path.Combine(x, path))
  .SelectMany(_ => Environment.GetEnvironmentVariable("PATHEXT").Split(';')
    .Concat(new String[] { Path.GetExtension(path) }), 
      (p, ext) => Path.ChangeExtension(p, ext))
  .Any(File.Exists);
// found => true(Perlがインストール済みの場合)

無理に一行で書こうとしたせいで冗長になってしまいました。

おまけ:もし見つかったらファイルパスを返す

最後のAnyをWhereに変えたらLinuxのwhichコマンドみたいなものもできました。LINQすごい。

whichっぽいの
var path = "perl";
var found = Environment.GetEnvironmentVariable("PATH").Split(';')
  .Select(x => Path.Combine(x, path))
  .SelectMany(_ => Environment.GetEnvironmentVariable("PATHEXT").Split(';')
    .Concat(new String[] { Path.GetExtension(path) }), 
      (p, ext) => Path.ChangeExtension(p, ext))
  .Where(File.Exists).FirstOrDefault();
// found => "c:\cygwin\bin\perl.EXE"(インストール済みの場合)

もし存在しないpathを指定すると、foundはnullとなります。