我的foreach循环看起来像这样:
foreach (var item in listOfFieldNames)
{
list.Where(s => s.GetType().GetProperty(item).GetValue(s, null).ToString().ToLower().Contains(searchString.ToLower()));
}
并且效果很好,但只要“s”为null,我就会得到nullRefferenceException
我想将s = null更改为s =“”但我不知道该怎么做。 你们能帮助我吗? 或者可能有一种方法可以跳过该空记录并继续循环而不会出现异常。那对我也有帮助。
试图解决这个问题已经有一段时间了,无法在任何地方找到答案:/ 尝试了一些.DefaultIfEmpty组合,但我不认为我知道要把它放在里面
答案 0 :(得分:3)
如果s有时为空,您可以使用:
list.Where(s => s != null && s.GetType().GetProperty(item).GetValue(s, null).ToString().ToLower().Contains(searchString.ToLower()));
稍后修改
所以问题是GetValue
返回null。在这种情况下,您可以使用null-coalescing运算符??
。我个人会扩展表达式,以便更容易阅读:
list.Where(s =>
{
var property = s.GetType().GetProperty(item);
var value = property.GetValue(s, null);
if (value == null) return false;
return value.ToString().Contains(searchString, StringComparison.OrdinalIgnoreCase);
});
答案 1 :(得分:1)
要在循环之前从列表中删除null
引用:
list.RemoveAll(s => s == null);
答案 2 :(得分:0)
// doing the .ToLower() on searchString before the query will improve performance.
// The original form would execute each pass (as a note .ToUpper() is slightly faster for
// conversions and comparisons since upper case letter come before lower case.
searchString = searchString.ToLower();
// assuming `list` is a List<T> this will allow the inner type of be used to get the
// property list. It is possible to check that getters exist for the properties which
// may be helpful if you have any setter only properties. If you work with any languages
// other than C# you may also want to exclude properties with indexers.
var properties = list.GetType()
.GetGenericArguments()[0].GetProperties()
.Where(p => listOfFieldNames.Contains(p.Name))
.ToList();
var query = from listItem in list
// if you have any setter only properties p.GetValue() will cause an exception
let values = properties.Select(p => p.GetValue(listItem))
.Where(p => p != null)
// you probably don't see the null coalesce but it is possible that .ToString()
// was over ridden and could allow null. The empty string is simplier to inline
// than to add another null filter after the .ToString()
.Select(p => (p.ToString() ?? "").ToLower())
// this will allow you to compare all properties that had values to your search
where values.Contains(searchString)
select listItem;
// this will create a new list that will contain all of the values from list that had at
// least one property that matched your searc hstring
var matched = query.ToList();