0

I have a HashSet as seen below:

public name {get; set; }

[JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace, TypeNameHandling = TypeNameHandling.Auto)]
public ICollection<T> data { get; set; }

public MyClass(string name)
{
    name = name;
    data = new HashSet<T>(new CustomComparer());
}

The comparer looks like:

public class CustomComparer: EqualityComparer<T>
{
    public override bool Equals(T x, T y)
    {
        return string.Equals(x.val, y.val, StringComparison.OrdinalIgnoreCase);
    }

    public override int GetHashCode(T obj)
    {
        return $"{obj?.val?.ToLowerInvariant()}-{obj?.val?.ToLowerInvariant()}".GetHashCode();
    }
}

Now, I have a unit test where I first create an instance of MyClass as:

var obj1 = new MyClass("test");
obj1.data.Add(CustomObject1);
obj1.data.Add(CustomObject2);

The next step I do is serialize and deserialize the object.

var jsonSerializerSettings = new JsonSerializerSettings();         
var serializedObject = JsonConvert.SerializeObject(obj1, jsonSerializerSettings);
var deserializedUserObject = JsonConvert.DeserializeObject<MyClass>(serializedObject, jsonSerializerSettings);

Now, when I try to add CustomObject1 back to the deserialized object (which is already present), it still adds to the set.

Not sure why this is happening. Any leads would be helpful.

FaizanHussainRabbani
  • 3,256
  • 3
  • 26
  • 46
learntogrow-growtolearn
  • 1,190
  • 5
  • 13
  • 37
  • 1
    How do your comparer & serialization work? – SLaks Feb 21 '18 at 21:55
  • I think you need to add JsonConstructor otherwise it uses default parameterless ctor. Here is a link to a possible duplicate question for assistance - https://stackoverflow.com/questions/23017716/json-net-how-to-deserialize-without-using-the-default-constructor –  Feb 21 '18 at 21:57
  • The problem is that `HashSet` is a collection, so [Json.NET](https://www.newtonsoft.com/json/help/html/serializationguide.htm#Lists) doesn't serialize the comparer (or other properties) of your `HashSet`, it only serializes the items. See for instance [Set the comparer for Newtonsoft.Json.JsonConvert to use for HashSet/Dictionary](https://stackoverflow.com/q/41875114/3744182) or [Json.NET Dictionary with StringComparer serialization](https://stackoverflow.com/q/20976338/3744182) for possible workarounds. – dbc Feb 22 '18 at 00:16
  • Why do you use `ObjectCreationHandling = ObjectCreationHandling.Replace`? – dbc Feb 22 '18 at 00:22
  • @SLaks The serialization is a default implementation of the JsonSerializationSettings and I have added the comparer to the question. – learntogrow-growtolearn Feb 22 '18 at 02:12
  • @dbc I have removed that now. See my answer below. – learntogrow-growtolearn Feb 22 '18 at 03:22

1 Answers1

0

This passed when I created a default constructor and initialized the data parameter as below.

public MyClass()
{
    data = new HashSet<T>(new CustomComparer());
}

Not sure if this is the correct way to achieve this. As there will be multiple instances of the data object being created unnecessarily. Is there any better way to get this done?

Imposing a [JsonConstructor] property on top of the parameterized constructor didn't work too.

NOTE: I removed the ObjectCreationHandling property from the JsonProperty attribute.

learntogrow-growtolearn
  • 1,190
  • 5
  • 13
  • 37