0

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?

  • Does this answer your question? [Use own IComparer with Linq OrderBy](https://stackoverflow.com/questions/985657/use-own-icomparert-with-linq-orderby) – BurnsBA Sep 20 '22 at 21:10
  • @BurnsBA it uses property.GetValue(x), which I thought was heavier for performance. my collection is actually a tree, and sort is called recursively. total items can be more than a million objects. – user2111255 Sep 21 '22 at 06:03
  • I don't think this error should happen unless MyList is defined as `ObservableCollection` rather than `ObservableCollection`. – sgmoore Sep 21 '22 at 09:27
  • You should post benchmarks, and your implementation showing how "sort is not performed correctly" – BurnsBA Sep 21 '22 at 12:54
  • C# is a language of types. What is `T` in your sample sort code? What type is `field`? – NetMage Sep 22 '22 at 00:15

1 Answers1

0

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
Anthony G.
  • 452
  • 2
  • 7