Giter Site home page Giter Site logo

comparerbuilder's Introduction

ComparerBuilder<T>

Class for building equality comparers and sort comparers.

ComparerBuilder<> helps to compare a complex types. It can create an EqualityComparer<> and/or a Comparer<> objects for you types. You just need to "add" expressions, that describes what data do you want to compare and, optionally, comparers - how to compare that data.

You can find reasons for making ComparerBuilder<> in this old post on RSDN (in Russian).

Now ComparerBuilder<> written on C# 6.0. You can compose a comparer builder from other comparer builders. Also, it supports "intercepted" comparers, that allows to intercept compare methods and, for example, print to a Debug when IEqualityComparer<>::Equals returns false or IComparer<>::Compare returns not 0. "Intercepted" comparers are helpful in a debugging scenarios.

static class Example
{
  private static void Main() {
    var builderSubData = new ComparerBuilder<SubData>()
      .Add(value => value.Test ?? String.Empty, StringComparer.OrdinalIgnoreCase);

    var builderBaseDataByTest1 = new ComparerBuilder<BaseData>()
      .Add(value => value.Test1 % 2);

    var builderBaseDataByTest2 = new ComparerBuilder<BaseData>()
      .Add(value => value.Test2 != null ? value.Test2.Value.Date : default(DateTime));

    var builderData = builderBaseDataByTest1
      .Add(builderBaseDataByTest2)
      .ConvertTo<Data>()
      .Add(value => value.SubData1, builderSubData);

    var equalityComparer = builderData.CreateEqualityComparer();
    var comparer = builderData.CreateComparer();

    var data1 = new Data(2, DateTime.Now, new SubData("a"));
    var data2 = new Data(4, DateTime.Now, new SubData("A"));
    var data3 = new Data(6, DateTime.Now, new SubData("c"));
    var data4 = new Data(1, null, new SubData("b"));

    var test1 = equalityComparer.Equals(data1, data2); // True, but may be False ;o)
    var test2 = equalityComparer.Equals(data2, data3); // False
    var test3 = comparer.Compare(data1, data4); // -1
  }
}

class BaseData
{
  public BaseData(int test1 = 0, DateTime? test2 = null) {
    Test1 = test1;
    Test2 = test2;
  }

  public int Test1 { get; }
  public DateTime? Test2 { get; }
}

class Data : BaseData
{
  public Data(int test1 = 0, DateTime? test2 = null, SubData subData1 = null) : base(test1, test2) {
    SubData1 = subData1;
  }

  public SubData SubData1 { get; }
}

class SubData
{
  public SubData(string test = null) {
    Test = test;
  }

  public string Test { get; }
}

comparerbuilder's People

Contributors

viivanov avatar

Stargazers

 avatar

Watchers

 avatar  avatar

comparerbuilder's Issues

Add support for lazy and recursive comparers

I need to support comparisons for types like it:

class ListNode<T>
{
  public T Value { get; set; }
  public ListNode<T> Previous { get; set; }
  public ListNode<T> Next { get; set; }

  public ListNotes Notes { get; set; }
}

class ListNotes
{
  public ListNode<string> Root { get; set; }
  public string SavePath { get; set; }
}
  • Support lazy comparers: when I create a comparer for ListNode I need c comparer for ListNotes, but when I constructing comparer for ListNotes I need a comparer for ListNode.
  • Support recursive comparers for case, when type contain data with this type.

Created Comparer<> compares a nullable properties incorrectly

The next test fails:

class BaseData
{
  public BaseData(int test1 = 0, DateTime? test2 = null) {
    Test1 = test1;
    Test2 = test2;
  }

  public int Test1 { get; }
  public DateTime? Test2 { get; }
}

public void CompareNullableProperty() {
  var comparer = new ComparerBuilder<BaseData>()
    .Add(value => value.Test2)
    .CreateComparerIntercepted();
  var items = new[] {
    new BaseData(test2: new DateTime(2015, 01, 01)),
    new BaseData(test2: null),
    new BaseData(test2: new DateTime(2015, 02, 01)),
    new BaseData(test2: null),
    new BaseData(test2: new DateTime(2015, 03, 01)),
  };
  Array.Sort(items, comparer);

  CollectionAssert.AllItemsAreNotNull(items);
  var previous = default(BaseData);
  foreach(var item in items) {
    if(previous != null) {
      Assert.IsTrue(previous.Test2 == null || previous.Test2 <= item.Test2, $"previous.Test2 == null || previous.Test2 [{previous.Test2}] <= item.Test2 [{item.Test2}]");
    }//if
    previous = item;
  }//for
}

with message

Assert.IsTrue failed. previous.Test2 [2015-03-01 00:00:00] <= item.Test2 []

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.