c# - Unexpected results with HashSet.Contains and custom IEqualityComparer -


i must have sort of misunderstanding respect using custom comparer hashset. collect lot of different types of data store intermediately json. in order operate on using json.net, jobject, jarray, , jtoken.

generally add bit of metadata inline stuff @ collection time, , prefixed "tbp_". need know if particular bit of data, represented jobject, has been collected before (or not). in order have custom iequalitycomparer extends implementation provided json.net. strips out metadata before checking value equality using provided implementation:

public class entrycomparer : jtokenequalitycomparer {     private static string _excludedprefix = "tbp_";      public jobject cloneforcomparison(jobject obj)     {         var clone = obj.deepclone() jobject;         var propertiestoremove = clone             .properties()             .where(p => p.name.startswith(_excludedprefix));          foreach (var property in propertiestoremove)         {             property.remove();         }          return clone;     }      public bool equals(jobject obj1, jobject obj2)     {         return base.equals(cloneforcomparison(obj1), cloneforcomparison(obj2));     }      public int gethashcode(jobject obj)     {         return base.gethashcode(cloneforcomparison(obj));     } } 

i use hashset track data i'm operating on, since need know if exists or not. initialize hashset instance of entrycomparer. tests are:

public class entrycomparertests {     entrycomparer comparer;     jobject j1;     jobject j2;      public entrycomparertests()     {         comparer = new entrycomparer();         j1 = jobject.parse(@"         {           'tbp_entry_date': '2017-03-25t21:25:53.127993-04:00',           'from_date': '1/6/2017',           'to_date': '2/7/2017',           'use': '324320',           'reading': 'act',           'kvars': '0.00',           'demand': '699.10',           'bill_amt': '$28,750.75'         }");         j2 = jobject.parse(@"         {           'tbp_entry_date': '2017-03-10t18:59:00.537745-05:00',           'from_date': '1/6/2017',           'to_date': '2/7/2017',           'use': '324320',           'reading': 'act',           'kvars': '0.00',           'demand': '699.10',           'bill_amt': '$28,750.75'         }");     }      [fact]     public void test_equality_comparer_gethashcode()     {           assert.equal(comparer.gethashcode(j1), comparer.gethashcode(j2));         assert.equal(true, comparer.equals(j1, j2));     }      [fact]     public void test_equality_comparer_hashset_contains()     {         var hs = new hashset<jobject>(comparer);         hs.add(j1);          assert.equal(true, hs.contains(j2));     } } 

test_equality_comparer_gethashcode() passes, test_equality_comparer_hashset_contains() fails. j1 , j2 should treated equal , according results of first test, missing here?

change signature of class:

public class entrycomparer : jtokenequalitycomparer, iequalitycomparer<jobject> 

otherwise gethashcode() , equals() used ones in base class (that has different "signature"... base class implements iequalitycomparer<jtoken>, reason methods aren't called hashset<>).

then there small bug properties removal:

var propertiestoremove = clone     .properties()     .where(p => p.name.startswith(_excludedprefix))     .toarray(); 

better "hide" jtokenequalitycomparer , make private field, like:

public class entrycomparer : iequalitycomparer<jobject> {     private static readonly jtokenequalitycomparer _comparer = new jtokenequalitycomparer();     private static readonly string _excludedprefix = "tbp_";      public static jobject cloneforcomparison(jobject obj)     {         var clone = obj.deepclone() jobject;         var propertiestoremove = clone             .properties()             .where(p => p.name.startswith(_excludedprefix))             .toarray();          foreach (var property in propertiestoremove)         {             property.remove();         }          return clone;     }      public bool equals(jobject obj1, jobject obj2)     {         return _comparer.equals(cloneforcomparison(obj1), cloneforcomparison(obj2));     }      public int gethashcode(jobject obj)     {         return _comparer.gethashcode(cloneforcomparison(obj));     } } 

Comments

Popular posts from this blog

javascript - Clear button on addentry page doesn't work -

c# - Selenium Authentication Popup preventing driver close or quit -

tensorflow when input_data MNIST_data , zlib.error: Error -3 while decompressing: invalid block type -