IGrouping.ToList() - 处理空值
IGrouping.ToList() - Handling null values
我有一个简单的单行 linq 查询来查找包含最高 属性 值的列表中的项目,并且仅当有一定数量的项目匹配时才用它们创建一个新列表标准。例如:
List<MyObject> objects = new List<MyObject>()
{
new MyObject() { MyValue = 6 },
new MyObject() { MyValue = 7 },
new MyObject() { MyValue = 7 },
new MyObject() { MyValue = 8 },
new MyObject() { MyValue = 8 },
};
int countRequired = 2;
List<MyObject> highestValue2Required = objects.GroupBy( o => o.MyValue )
.OrderByDescending( g => g.Key )
.Where( g => g.Count() == countRequired )
.FirstOrDefault()
.ToList();
如果我的列表中有满足这些条件的数据,将创建一个包含两个 MyObject
实例的新列表,其中 MyValue = 8
.
但是,如果没有符合条件的数据,我会遇到异常,因为查询的 IGrouping
结果为空,并且对此调用 ToList()
不起作用。例如:
int countRequired = 3;
List<MyObject> highestValue3Required = objects.GroupBy( o => o.MyValue )
.OrderByDescending( g => g.Key )
.Where( g => g.Count() == countRequired )
.FirstOrDefault()
.ToList();
因为列表中只有两个 MyObject
的实例,其中 MyValue
等于最大值(即 8),查询抛出异常
System.ArgumentNullException: 'Value cannot be null.
是否可以使用此空值来 return 我的 "one line" 查询中的空列表?
最明显的方法是删除 ToList()
调用并简单地 return 一个 IGrouping
结果,并且只在它不为空时调用 ToList()
,但我很好奇它是否可以在线完成。
您需要使用 null-conditional operator after calling FirstOrDefault()
. If this method returns null
, the result of the entire expression will be null. You can then use the null-coalescing operator 将 null
结果转换为空列表。
var highestValue3Required = objects.GroupBy( o => o.MyValue )
.OrderByDescending( g => g.Key )
.Where( g => g.Count() == countRequired )
.FirstOrDefault()
?.ToList() ?? new List<MyObject>();
问题出在.FirstOrDefault().ToList()
。由于 FirstOrDefault()
可能 return 一个值 或 NULL,你不能直接调用 .ToList()
.
如果您希望在没有匹配项的情况下最终结果为 null
,您可以简单地向 FirstOrDefault()
调用添加一个空调节器 (?
):
List<MyObject> highestValue2Required = objects.GroupBy(o => o.MyValue)
.OrderByDescending(g => g.Key)
.Where(g => g.Count() == countRequired)
.FirstOrDefault()?
.ToList();
但是,如果您对空值不满意并且想要一个空列表,则可以将以下扩展方法添加到您的项目中以便能够使用单行代码:
static class Extensions
{
public static IEnumerable<T> OrEmptyIfNull<T>(this IEnumerable<T> source)
{
return (source ?? Enumerable.Empty<T>());
}
}
现在,您可以轻松地执行以下操作:
List<MyObject> highestValue2Required = objects.GroupBy(o => o.MyValue)
.OrderByDescending(g => g.Key)
.Where(g => g.Count() == countRequired)
.FirstOrDefault()
.OrEmptyIfNull()
.ToList();
我有一个简单的单行 linq 查询来查找包含最高 属性 值的列表中的项目,并且仅当有一定数量的项目匹配时才用它们创建一个新列表标准。例如:
List<MyObject> objects = new List<MyObject>()
{
new MyObject() { MyValue = 6 },
new MyObject() { MyValue = 7 },
new MyObject() { MyValue = 7 },
new MyObject() { MyValue = 8 },
new MyObject() { MyValue = 8 },
};
int countRequired = 2;
List<MyObject> highestValue2Required = objects.GroupBy( o => o.MyValue )
.OrderByDescending( g => g.Key )
.Where( g => g.Count() == countRequired )
.FirstOrDefault()
.ToList();
如果我的列表中有满足这些条件的数据,将创建一个包含两个 MyObject
实例的新列表,其中 MyValue = 8
.
但是,如果没有符合条件的数据,我会遇到异常,因为查询的 IGrouping
结果为空,并且对此调用 ToList()
不起作用。例如:
int countRequired = 3;
List<MyObject> highestValue3Required = objects.GroupBy( o => o.MyValue )
.OrderByDescending( g => g.Key )
.Where( g => g.Count() == countRequired )
.FirstOrDefault()
.ToList();
因为列表中只有两个 MyObject
的实例,其中 MyValue
等于最大值(即 8),查询抛出异常
System.ArgumentNullException: 'Value cannot be null.
是否可以使用此空值来 return 我的 "one line" 查询中的空列表?
最明显的方法是删除 ToList()
调用并简单地 return 一个 IGrouping
结果,并且只在它不为空时调用 ToList()
,但我很好奇它是否可以在线完成。
您需要使用 null-conditional operator after calling FirstOrDefault()
. If this method returns null
, the result of the entire expression will be null. You can then use the null-coalescing operator 将 null
结果转换为空列表。
var highestValue3Required = objects.GroupBy( o => o.MyValue )
.OrderByDescending( g => g.Key )
.Where( g => g.Count() == countRequired )
.FirstOrDefault()
?.ToList() ?? new List<MyObject>();
问题出在.FirstOrDefault().ToList()
。由于 FirstOrDefault()
可能 return 一个值 或 NULL,你不能直接调用 .ToList()
.
如果您希望在没有匹配项的情况下最终结果为 null
,您可以简单地向 FirstOrDefault()
调用添加一个空调节器 (?
):
List<MyObject> highestValue2Required = objects.GroupBy(o => o.MyValue)
.OrderByDescending(g => g.Key)
.Where(g => g.Count() == countRequired)
.FirstOrDefault()?
.ToList();
但是,如果您对空值不满意并且想要一个空列表,则可以将以下扩展方法添加到您的项目中以便能够使用单行代码:
static class Extensions
{
public static IEnumerable<T> OrEmptyIfNull<T>(this IEnumerable<T> source)
{
return (source ?? Enumerable.Empty<T>());
}
}
现在,您可以轻松地执行以下操作:
List<MyObject> highestValue2Required = objects.GroupBy(o => o.MyValue)
.OrderByDescending(g => g.Key)
.Where(g => g.Count() == countRequired)
.FirstOrDefault()
.OrEmptyIfNull()
.ToList();