0

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

2
  • What version of VS/C# are you using? Commented Aug 31, 2016 at 19:50
  • VS2013 so it's c# 5 I guess Commented Aug 31, 2016 at 19:55

3 Answers 3

3

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);
});
Sign up to request clarification or add additional context in comments.

1 Comment

list.Where(s => s.GetType().GetProperty(item).GetValue(s, null) != null && s.GetType().GetProperty(item).GetValue(s, null).ToString().ToLower().Contains(searchString.ToLower())); worked :D super ugly but works :D
1

To remove null references from your list prior to the loop:

list.RemoveAll(s => s == null);

Comments

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

1 Comment

Looks really clear. Thanks. Will try it tomorrow. Btw. isn't it better not to declare so many variables? I'm a junior dev, but want to get best practices from the start. That's why I'm asking.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.