I'm trying to build a function that will sort a list of T
by specified field (as a string
name of the field), including fields in nested objects. I can create expression like this: l.FooObject.Name
, but I don't know how to create an expression like this: l.FooObject?.Name
or at least like this (l.FooObject == null) ? default : l.FooObject.Name
This is my function:
public static List<T> Sort(List<T> sourceList, string sortBy)
{
var propertyNames = sortBy.Split('.');
var parameter = Expression.Parameter(typeof(T), "x");
Expression propertyAccess = parameter;
foreach (var propertyName in propertyNames)
{
propertyAccess = Expression.PropertyOrField(propertyAccess, propertyName);
}
var propertyValue = Expression.Convert(propertyAccess, typeof(object));
var sortExpression = Expression.Lambda<Func<T, object>>(propertyValue, parameter);
var query = sourceList.AsQueryable();
query = query.OrderBy(sortExpression);
return query.ToList();
}
The problem is this line: propertyAccess = Expression.PropertyOrField(propertyAccess, propertyName);
The expression created by this function will throw System.NullReferenceException
if Nested object is null. For example having these two classes:
public class Foo
{
public int Id { get; set; }
public string? Name { get; set; }
}
public class Bar
{
public int Id { get; set; }
public Foo? FooObject { get; set; }
}
If I want to sort List<Bar>
by "FooObject.Name" it will throw an exception if there is at least one Bar
object with null FooObject
. It will build expression like this l.FooObject.Name
. I need l.FooObject?.Name
Thanks for help!