0

Consider the Node class. Using Newtonsoft to convert it into the JSON.

class Node {
   IList<Node> Nodes { get; }
}

I'm currently implementing default sorting logic as -

class Node : IComparable<Node> {
   IList<Node> Nodes { get; }

   public int CompareTo(Node node) {
      // some default sorting logic
   }
}

Newtonsoft, while serializing using it, and giving JSON with Nodes sorted in same logic.

string jsonString = JsonConvert.SerializeObject(
   deserializedObject, 
   Formatting.None, 
   new JsonSerializerSettings
   {
            // some settings
   });

Question: Now, I want to pass something like IComparer to JsonConvert.SerializeObject() method, so that JSON should have Nodes collection in a new sorting logic.

In some way I want to give freedom to caller to sort the collection in their way rather than default one, which would be used otherwise.

Don't know if there is a easy way of doing it? Any suggestions please?

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
unknown_boundaries
  • 1,482
  • 3
  • 25
  • 47
  • You can provide that freedom once you de-serialize the object, user can use the custom IComparer to rearrange the items in the List – Mrinal Kamboj Mar 28 '16 at 07:36
  • In some way, I want to do it while getting JSON. It's very big JSON (~75 MB), and we don't want to involve deserialization costs, and serializing again, because end consumer needs JSON. – unknown_boundaries Mar 28 '16 at 07:38
  • Then you need a custom sorting mechanism before object is serialized to Json, Take that as user input, translate into a custom DS, do the comparison and rearrangement , before serialized Json data is send across – Mrinal Kamboj Mar 28 '16 at 07:41

1 Answers1

2

There is no way to pass IComparer to JsonConvert.SerializeObject(). You can Sort the list of object using custom sort(IComparer) logic and pass the list to Serialization.

But, as you said, you can pass IComparer to Custom method and accomplish the task. as follows,

class Node
    {
        IList<Node> Nodes { get; set; }
        internal string Serialize(IComparer<Node> comparer)
        {
            Nodes = (IList<Node>)Nodes.OrderBy(c => c, comparer);
            return JsonConvert.SerializeObject(Nodes, Formatting.Indented, new JsonSerializerSettings() { });
        }
    }
    class SortHelper : IComparer<Node>
    {
        int IComparer<Node>.Compare(Node x, Node y)
        {
            // compare object x and y by custom logic
            return 0;
        }
    }

and call the following method with the above writter custom IComparer

string jsonString = node.Serialize(new SortHelper());
Venu prasad H S
  • 231
  • 1
  • 8
  • Not as IComparer, but as a user input in a custom data structure, which can be translated into something similar to IComparer for processing before serialization – Mrinal Kamboj Mar 28 '16 at 08:07
  • This is indeed a good example +1, where IComparer is used to achieve the purpose, and Custom Comparer can be achieved through user input and supplied to the sorting functions. For more clarity also check difference between IComparer and IComparable http://stackoverflow.com/questions/5980780/difference-between-icomparable-and-icomparer – Mrinal Kamboj Mar 28 '16 at 10:31