ドラックアンドロップで複数のファイルが文字配列で渡されて最初の1件のみ処理したい。ただし、対応しないファイルが含まれる可能性があるので、フィルター処理を行う必要がありますが、フィルター処理にによってファイル件数が0件になる可能性があります。このような状況で配列の要素数が0~n件の中から1件のみ処理する方法を考えてみたいと思います。
案1
static void Test1(IEnumerable<string> array)
{
// 1.if
string? s = array.FirstOrDefault();
if (s is not null)
{
// 処理
Console.WriteLine($"1.{s}");
}
}
FirstOrDefault()で最初の一件を取得無い場合はでdefaultをかえす。要素のstringのdefaultはnullになるなるらしく0件の場合nullチェックが必要となる。
案2
static void Test2(IEnumerable<string> array)
{
// 2.foreach
foreach(string x in array)
{
// arrayの要素が0の場合ここにはこない
// 処理
Console.WriteLine($"2.{x}");
// 1件処理したらforeachを終了
break;
}
}
foreachで取得することで要素数が0の場合ループに入らない。ループは1回のみとする為breakするようにしてみた。
案3
static void Test3(IEnumerable<string> array)
{
foreach(var x in array.Take(1))
{
// 処理
Console.WriteLine($"3.{x}");
}
}
Take(1)をつかい要素が1つのコレクションに変換しforeachで処理。もとのコレクションの要素が0の場合Take(1)で返される要素も0となるのでforeachのループは実行されない。
案4
static void Test4(string[] array)
{
// 4.for
for(int i=0; i < (1 < array.Length ? 1 : 0); i++)
{
// arrayの要素が0の場合ここにはこない
// 処理
Console.WriteLine($"4.{array[i]}");
}
}
案3をforで再現してみた。
感想
良し悪しではなく筆者の好みとして、案1はnullチェックはしたくない。案2はbreakが気に入らない。案4はforの終了判定が不自然な感じがします。消去法で案3を採用することになりそうです。
また、案1,2,4は最初の1件目の文字列が取得できる場合処理を行い、そうで無い場合処理しないという条件分岐ですが、案3の場合コレクションの要素数を0~1にすることでループ処理としているので、take(1)以降もLinqでつなげることが出来そうです。
コメント