如何确保 FirstOrDefault < KeyValuePair > 已返回值

下面是我正在尝试做的事情的一个简化版本:

var days = new Dictionary<int, string>();
days.Add(1, "Monday");
days.Add(2, "Tuesday");
...
days.Add(7, "Sunday");


var sampleText = "My favorite day of the week is 'xyz'";
var day = days.FirstOrDefault(x => sampleText.Contains(x.Value));

由于字典中不存在“ xyz”,FirstOrDefault 方法将不返回有效值。我希望能够检查这种情况,但是我意识到我不能将结果与“ null”进行比较,因为 KeyValuePair 是一个 struc。下列代码无效:

if (day == null) {
System.Diagnotics.Debug.Write("Couldn't find day of week");
}

如果您尝试编译代码,VisualStudio 将引发以下错误:

Operator '==' cannot be applied to operands of type 'System.Collections.Generic.KeyValuePair<int,string>' and '<null>'

如何检查 FirstOrDefault 是否返回了有效值?

45838 次浏览

FirstOrDefault doesn't return null, it returns default(T).
You should check for:

var defaultDay = default(KeyValuePair<int, string>);
bool b = day.Equals(defaultDay);

From MSDN - Enumerable.FirstOrDefault<TSource>:

default(TSource) if source is empty; otherwise, the first element in source.

Notes:

This is the most clear and concise way in my opinion:

var matchedDays = days.Where(x => sampleText.Contains(x.Value));
if (!matchedDays.Any())
{
// Nothing matched
}
else
{
// Get the first match
var day = matchedDays.First();
}

This completely gets around using weird default value stuff for structs.

You can do this instead :

var days = new Dictionary<int?, string>();   // replace int by int?
days.Add(1, "Monday");
days.Add(2, "Tuesday");
...
days.Add(7, "Sunday");


var sampleText = "My favorite day of the week is 'xyz'";
var day = days.FirstOrDefault(x => sampleText.Contains(x.Value));

and then :

if (day.Key == null) {
System.Diagnotics.Debug.Write("Couldn't find day of week");
}

Select a list of valid values then check if it contains your day.Value; like this:

var days = new Dictionary<int, string>();
days.Add(1, "Monday");
days.Add(2, "Tuesday");
days.Add(7, "Sunday");
var sampleText = "My favorite day of the week is 'xyz'";
var day = days.FirstOrDefault(x => sampleText.Contains(x.Value));


//check that FirstOrDefault has returned a valid value
if (days.Select(x=>x.Value).Contains(day.Value))
{
//VALID
}
else
{
System.Diagnostics.Debug.Write("Couldn't find day of week");
}

Here's another example using a list of key value pairs:

var days = new List<KeyValuePair<int, string>>();
days.Add(new KeyValuePair<int, string>(1, "Monday"));
days.Add(new KeyValuePair<int, string>(1, "Tuesday"));
days.Add(new KeyValuePair<int, string>(1, "Sunday"));
var sampleText = "My favorite day of the week is 'xyz'";
var day = days.FirstOrDefault(x => sampleText.Contains(x.Value));


//check that FirstOrDefault has returned a valid value
if (days.Select(x => x.Value).Contains(day.Value))
{
//VALID
}
else
{
System.Diagnostics.Debug.Write("Couldn't find day of week");
}

Hope this helps someone!