简体   繁体   中英

If null then set it to empty string lambda expression in linq

Im having a foreach loop that looks like this:

 foreach (var item in listOfFieldNames)
                {
    list.Where(s =>  s.GetType().GetProperty(item).GetValue(s, null).ToString().ToLower().Contains(searchString.ToLower()));
}

and it works pretty well, but whenever "s" is a null I get nullRefferenceException

I would like to change my s = null into s = " " but I don't know how to do it. Could you guys help me? Or maybe there is a method to skip that null record and continue my loop without getting an exception. That would also help me.

Trying to figure this out for quite some time and can't find the answer anywhere :/ Tried some .DefaultIfEmpty combinations but I don't think I know what to put inside it

If s comes null sometimes, you could use:

list.Where(s => s != null && s.GetType().GetProperty(item).GetValue(s, null).ToString().ToLower().Contains(searchString.ToLower()));

Later edit

So the problem is that GetValue returns null. In this case, you can use the null-coalescing operator ?? . I would personally expand the expression so it's easier to read:

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);
});

要在循环之前从列表中删除null引用,请执行以下操作:

list.RemoveAll(s => s == null);
// 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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM