Dynamic linq orderBy by non existent field

Viewed 38

I have an ObservableCollection, which consists of objects from a base type and derived type both.

public class BaseClass    
{
      public string First{get;set}
      public ObservableCollection<BaseClass> Items {get;set}
}
public class DerivedClass : BaseClass
{
      public Second{get;set}
}

the usage is with:

ObservableCollection<BaseClass> MyList;
MyList.Add(new BaseClass());
MyList.Add(new DerivedClass());

The requirement is to sort this collection on different properties, so to avoid "switch case" I have used dyanmic orderBy, as in:

MyList = new ObservableCollection<BaseClass>(MyList.AsQueryable().OrderBy(field));

MyList is actually a tree, and the sort is called recursively for ~1,000,000 items total, so performance is crucial here. I understood the dynamic orderBy is faster that reflection - getting property value for field name and comparing it. (or am I wrong?!?)

Now the problem is some properties exist in the derived type, but not in base, so sort is not performed correctly. How can I implement some comparer to handle missing fields as null/empty?

1 Answers

You could implement IComparer and inspect the types but it may not be any cleaner than another solution:

public class CustomComparer : IComparer<BaseClass>
{
    public int Compare(BaseClass a, BaseClass b)
    {
        //whatever custom logic you want to use for sorting can be added here 
        if (a is DerivedClass ac && b is DerivedClass bc) 
           return Compare(ac.DerivedId, bc.DerivedId);

        //.. would have to handle a being Derived when b is not, and opposite.

        return Compare(a.Id, b.Id);
    }

    private int Compare(int a, int b)
    {
        if (a > b)
            return 0;

        if (a < b)
            return -1;

        return 1;
    }

}

public class BaseClass
{
    public int Id { get; set; }
}

public class DerivedClass : BaseClass
{
    public int DerivedId { get; set; } // not on base
}

You could simply call:

CustomComparer comp = new CustomComparer();
list.Sort(comp); // Sort is extension on List, not ObservableCollection
Related