我有这个方法
private IList<Order> FilterOrders(string filterText)
{
string filterTextLowerCase = filterText.ToLower();
var filtered = _orders.Where(order =>
order.OrderIdFullOrderNumber.ToLower().Contains(filterTextLowerCase) ||
order.Name.ToLower().Contains(filterTextLowerCase) ||
order.Status.ToLower().Contains(filterTextLowerCase) ||
order.TimeRemaining.ToLower().Contains(filterTextLowerCase) ||
order.Address.ToLower().Contains(filterTextLowerCase) ||
order.City.ToLower().Contains(filterTextLowerCase) ||
order.State.Abbrev.ToLower().Contains(filterTextLowerCase) ||
order.PostalCode.ToLower().Contains(filterTextLowerCase)).ToList();
return filtered;
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,属性中可能存在nullreference异常,在这个Where表达式中检查null的最佳方法是什么?
Jon*_*oll 10
如果您使用的是C#6,则可以?.在访问对象属性或方法之前添加空检查操作符:order?.State?.ToLower()....
见这对新的空检查经营者的详细信息.
如果您使用的是较低版本,则必须为每个where子句添加额外的空检查: .Where(order => (order.State != null && order.State.ToLower()....)
添加此扩展方法:
public static string NullSafeToLower(this string s)
{
if (s == null)
{
s = string.Empty;
}
return s.ToLower();
}
Run Code Online (Sandbox Code Playgroud)
然后将对“ ToLower”的调用替换为对“ NullSafeToLower”的调用。
即使问题已经回答,另一种选择是:
var myVar = orders.Where(o => (o.SomeProperty ?? "").ToLower() == "someValue");
虽然这不是那么漂亮,但如果您只需要一次或两次,这可能不像扩展方法那样“繁重”,但是如果您需要这样做很多(如您的示例),那么其中之一作为答案列出的扩展方法将为您提供更好的服务。
作为参考,我不得不这样做,因为我当时工作的构建环境还不支持 C# 6.0。如果您在缓慢采用的环境中工作(它发生了!),最好有回退技巧。就是想把这个扔出去。:)
不幸的是,我此时无法使用 C# 6.0 功能。
我最终创建了一个扩展方法来过滤列表,与另一个扩展方法 Contains 进行比较,该方法接受 @robert-mckee 建议的 StringComparison 参数并从 @jeppe-stig-nielsen 演示。
public static IList<Order> FilterOrders(this IList<Order> orders, string filterText)
{
var filtered = orders.Where(order =>
order.OrderIdFullOrderNumber.Contains(filterText, StringComparison.OrdinalIgnoreCase) ||
order.Name.Contains(filterText, StringComparison.OrdinalIgnoreCase) ||
order.Status.Contains(filterText, StringComparison.OrdinalIgnoreCase) ||
order.TimeRemaining.Contains(filterText, StringComparison.OrdinalIgnoreCase) ||
order.Address.Contains(filterText, StringComparison.OrdinalIgnoreCase) ||
order.City.Contains(filterText, StringComparison.OrdinalIgnoreCase) ||
order.State.Abbrev.Contains(filterText, StringComparison.OrdinalIgnoreCase) ||
order.PostalCode.Contains(filterText, StringComparison.OrdinalIgnoreCase)).ToList();
return filtered;
}
public static bool Contains(this string source, string value, StringComparison comparison)
{
if (string.IsNullOrWhiteSpace(source))
{
return false;
}
return source.IndexOf(value, comparison) >= 0;
}
Run Code Online (Sandbox Code Playgroud)