public ComparerBuilder <TItem> Compare <TField>(Func <TItem, TField> expression, IComparer <TField> comparer, OrderFlavour flavour = OrderFlavour.Default) { if (expression == null) { throw new ArgumentNullException("expression"); } if (comparer == null) { throw new ArgumentNullException("comparer"); } Func <object, object, int> fieldComparison = delegate(object x, object y) { var f = flavour; // stack is faster then heap bool areNullsEarly = (f & OrderFlavour.NullGoesEarly) != 0; bool isBackward = (f & OrderFlavour.Backward) != 0; // 1. x & y are unconditionally NOT NULL and type of them is defenitely TItem // 2. The compiler replaces null comparisons with a call to HasValue for nullable types TField xField = expression((TItem)x); TField yField = expression((TItem)y); if (TypeInfo <TField> .IsReferenceType && ReferenceEquals(xField, yField)) { return(0); } if (xField == null && yField == null) { return(0); } if (xField == null) { return(areNullsEarly ? -1 : 1); } if (yField == null) { return(areNullsEarly ? 1 : -1); } int ret = comparer.Compare(xField, yField); return(isBackward ? -ret : ret); }; _Comparisons.Add(new FieldMeta() { Comparison = fieldComparison, }); return(this); }
public Comparison <TItem> GetComparison(OrderFlavour flavour = OrderFlavour.Default) { // ThreadSafe return(new ItemComparer <TItem>(_Comparisons, OrderFlavour.Default).Compare); }
public IComparer <TItem> GetComparer(OrderFlavour flavour = OrderFlavour.Default) { return(new ItemComparer <TItem>(_Comparisons, flavour)); }
public ComparerBuilder <TItem> CompareString(Func <TItem, string> expression, StringComparer comparer, OrderFlavour flavour = OrderFlavour.Default) { return(Compare(expression, comparer, flavour)); }
public ComparerBuilder <TItem> Compare <TField>(Func <TItem, TField> expression, OrderFlavour flavour = OrderFlavour.Default) { return(Compare(expression, Comparer <TField> .Default, flavour)); }
public ItemComparer(List <FieldMeta> fields, OrderFlavour orderFlavour) { _Fields = fields; _OrderFlavour = orderFlavour; }