0

I want to overwrite an existing object with some fields and dicitionary.

class MyInt {int value; int enchantment} // stat
enum MyEnum {FIRE, COLD, POISON}
class Creature {
    MyInt hp;
    MyInt mana;
    Dictionary<MyEnum, MyInt> resists;
}
...
Creature c = ...; // assigned elswhere (from Unity-Inspector)
JsonConvert.PopulateObject(json_str, c);

After Populating object from JSon, fields hp and mana are correctly overwritten, but values of dictionary resists are recreated. Dictionary itself will be not recreated and has same hash_code after populating, what is correct. But the exemplars of MyInt will be recrated (with new HashCodes etc.).

My JSON Looks like that:

 {
   "hp": "3",
   "mana": "7",
   "resists": {
     "FIRE": "11",
     "COLD": "0",
     "POISON": "33"
   }
 }

I have found setting ObjectCreationHandling = ObjectCreationHandling.Reuse but unfortunately it is same as Auto and does not help in this case.

Is any way to force JConvert overwrite the values of dictionary, without recreating new MyInt objects, like it works for fields hp/mana? Something like JConvert.PopulateTransitive(...)?

AvrDragon
  • 7,139
  • 4
  • 27
  • 42
  • 1
    I'm a little unclear on the problem, might you please [edit] your question to share a [mcve]? Your code doesn't compile (fields are private) but when I fix that, `c.resists` is not replaced. See https://dotnetfiddle.net/qZ0UxH. Also the JSON in your question can't be deserialized to your data model because `"3"` cannot be deserialized to `MyInt`, see https://dotnetfiddle.net/oF7gFj. – dbc Feb 25 '21 at 17:10
  • 1
    But maybe you're looking for `DictionaryMergeConverter` from [this answer](https://stackoverflow.com/a/62802477/3744182) to [Json.net - How to preserve dictionary value references when populating a dictionary?](https://stackoverflow.com/q/62783715/3744182)? – dbc Feb 25 '21 at 17:13
  • @dbc it is pseudocode to make example as little as possible. Yes correctly, resists itself will be not replaced. The problem that 3 values inside resists will be recreated. I want also to overwrite values of dictionary, without recreating them. (Background: theese objects are added to some collections that must be updated if objects are recreated) – AvrDragon Feb 25 '21 at 17:13
  • Psuedocode can be unhelpful if we're trying to reproduce your problem. For instance `DictionaryMergeConverter` might not work for you if you have some `TypeConverter` that converts `MyInt` from and to a string. If you do, Json.NET will use it and you will be unable to populate existing instances. But I can't test that without a real example. – dbc Feb 25 '21 at 17:15
  • @dbc Yes, exactly a have a TypeConverter for MyInt just to store values like "x / y". Otherwise DictionaryMergeConverter sounds right for this problem. So basically i need to overwrite a dictionary preserving values with same key. And values are my own class with it's own TypeConverter. Oh yes, i will update the question to make minimar reproducible example really work. – AvrDragon Feb 25 '21 at 17:20
  • Json.NET is not going to be able to populate existing instances of `MyInt` when you have a `TypeConverter` assigned. It will use the type converter and call `ConvertFrom()` and `ConvertTo()` to convert from and to the string representation -- but these methods have no way to populate an existing instance. There's no `TypeConverter.PopulateFrom()` or `PopulateTo()`... – dbc Feb 25 '21 at 17:24
  • ... You will need to disable use of the type converter during serialization if you want to populate an existing instance. To do that see [Newtonsoft.JSON cannot convert model with TypeConverter attribute](https://stackoverflow.com/q/31325866/3744182). – dbc Feb 25 '21 at 17:24
  • @dbc Ah, i have looked question from the second comment: it is exactly the same. So my question is a dublicate. thank you. – AvrDragon Feb 25 '21 at 17:25
  • Right, if you combine [Json.net - How to preserve dictionary value references when populating a dictionary?](https://stackoverflow.com/q/62783715/3744182) with [Newtonsoft.JSON cannot convert model with TypeConverter attribute](https://stackoverflow.com/q/31325866/3744182) you may be all set. Give it a try and see if it works. – dbc Feb 25 '21 at 17:26

0 Answers0