I have (or wanted to have) some code like this:
IDictionary<string,int> dict = new Dictionary<string,int>(); // ... Add some stuff to the dictionary. // Try to find an entry by value (if multiple, don't care which one). var entry = dict.FirstOrDefault(e => e.Value == 1); if ( entry != null ) { // ^^^ above gives a compile error: // Operator '!=' cannot be applied to operands of type 'System.Collections.Generic.KeyValuePair<string,int>' and '<null>' }
I also tried changing the offending line like this:
if ( entry != default(KeyValuePair<string,int>) )
But that also gives a compile error:
Operator '!=' cannot be applied to operands of type 'System.Collections.Generic.KeyValuePair<string,int>' and 'System.Collections.Generic.KeyValuePair<string,int>'
What gives here?
The major difference between First and FirstOrDefault is that First() will throw an exception if there is no result data for the supplied criteria whereas FirstOrDefault() returns a default value (null) if there is no result data.
The default value for reference and nullable types is null . The FirstOrDefault method does not provide a way to specify a default value. If you want to specify a default value other than default(TSource) , use the DefaultIfEmpty<TSource>(IEnumerable<TSource>, TSource) method as described in the Example section.
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> }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With