如果为null,则将其设置为linq中的空字符串lambda表达式

时间:2016-08-31 19:46:25

标签: c# linq generics lambda

我的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组合,但我不认为我知道要把它放在里面

3 个答案:

答案 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();