0. はじめに
Freeradicalの中の人、yamarahです。
Dictionary
に対してFirstOrDefault
すると、一致がない場合にKeyVaulePair(default, default)
が得られます。ちょっと困る場合があるよね、という話です。
1. どういった場合に困る
FirstOrDefault
で困るのはDictionary
に、Key
もしくはVaule
がDefault
値の要素を含む場合です。
int
で0
や、string
でnull
を許容している場合など。
これらの場合に、含まれている要素なのか検索ヒットなしかの区別がつきません。
Dictionary<int, string?> dic = new() { { 0, null } };
var pair1 = dic.First();
var pair2 = dic.FirstOrDefault(_ => false);
// 以下はTrueになる
Console.WriteLine(pair1.Key == pair2.Key && pair1.Value == pair2.Value);
もちろん、それぞれの状況に応じて回避方法はあるでしょう。
しかし、毎度回避方法を探るのではなく、ただ単純にFirstOrNull
が欲しいのです。
2. 作ってみた
ということで、作りました。
static class CollectionExtensions
{
public static KeyValuePair<TKey, TValue>? FirstOrNull<TKey, TValue>(this IDictionary<TKey, TValue> source, Func<KeyValuePair<TKey, TValue>, bool> predicate) where TKey : notnull
{
foreach(var pair in source)
{
if (predicate(pair)) return pair;
}
return null;
}
}
これならば、
Dictionary<int, string?> dic = new() { { 0, null } };
var pair = dic.FirstOrNull(_ => false);
Console.WriteLine(pair is null); // True
となり、満足です。