Dictionary.FirstOrDefault() how to determine if a result was found
Do it this way:
if ( entry.Key != null )
The thing is that the FirstOrDefault
method returns a KeyValuePair<string, int>
which is a value type, so it cannot ever be null
. You have to determine if a value was found by checking if at least one of its Key
, Value
properties has its default value. Key
is of type string
, so checking that for null
makes sense considering that the dictionary could not have an item with a null
key.
Other approaches you could use:
var entry = dict.Where(e => e.Value == 1)
.Select(p => (int?)p.Value)
.FirstOrDefault();
This projects the results into a collection of nullable ints, and if that is empty (no results) you get a null -- there's no way you can mistake that for the int
that a successful search would yield.
Regardless of the types of Key and Value, you could do something like this:
static void Main(string[] args)
{
var dict = new Dictionary<int, string>
{
{3, "ABC"},
{7, "HHDHHGKD"}
};
bool found = false;
var entry = dict.FirstOrDefault(d => d.Key == 3 && (found=true));
if (found)
{
Console.WriteLine("found: " + entry.Value);
}
else
{
Console.WriteLine("not found");
}
Console.ReadLine();
}
Jon's answer will work with Dictionary<string, int>
, as that can't have a null key value in the dictionary. It wouldn't work with Dictionary<int, string>
, however, as that doesn't represent a null key value... the "failure" mode would end up with a key of 0.
Two options:
Write a TryFirstOrDefault
method, like this:
public static bool TryFirstOrDefault<T>(this IEnumerable<T> source, out T value)
{
value = default(T);
using (var iterator = source.GetEnumerator())
{
if (iterator.MoveNext())
{
value = iterator.Current;
return true;
}
return false;
}
}
Alternatively, project to a nullable type:
var entry = dict.Where(e => e.Value == 1)
.Select(e => (KeyValuePair<string,int>?) e)
.FirstOrDefault();
if (entry != null)
{
// Use entry.Value, which is the KeyValuePair<string,int>
}