0

I have a variable of type ExtendedUserModel which after deserialization, becomes an object of type Dictionary<object,object>. (that Dictionary<object,object> is the result of deserialization using MessagePack)

At compile time I cannot cast Dictionary<object,object> to ExtendedUserModel for reasons that are related to how the codebase was implemented. But I do have access to the variable named type which is basically equal to typeof(ExtendedUserModel)

The workaround: The followings can successfully do the casting at runtime without the need for type to have IConvertible interface implemented in it:

var castedObject = Newtonsoft.Json.JsonConvert.DeserializeObject(JsonConvert.SerializeObject(variable), type);

or:

var castedObject = System.Text.Json.JsonSerializer.Deserialize(JsonSerializer.Serialize(variable), type);

How Can I achieve the same without resorting to this serialization and deserialization?

Note:

  • As I said, using Convert.ChangeType(variable, type); is not an option because we cannot enforce the implementation of IConvertible interface.
  • I tried this response too, but I got: System.InvalidOperationException: No coercion operator is defined between types 'System.Collections.Generic.Dictionary`2[Sys tem.Object,System.Object]' and 'CoreConsoleApp1.ExtendedUserModel'.
wiki
  • 1,877
  • 2
  • 31
  • 47
  • 1
    You have to post your json if you really need some help. You can also show us the classes you have used to get the error – Serge Sep 18 '22 at 17:02
  • @Serge don't know how that's relevant to the title, but `ExtendedUserModel` is a simple class with two string properties. – wiki Sep 18 '22 at 17:11
  • 1
    At the time you are deserializing, do you know the final type `ExtendedUserModel`? If so, why not deserialize to it directly? If not, how do you expect to infer the type, given that JSON objects do not contain any type information? – dbc Sep 18 '22 at 17:15
  • 1
    *How these libraries can convert an object to the actual type using Type?* -- they don't, and can't, because that isn't how they are implemented. They deserialize directly from the JSON using a streaming reader (or reader of a readonly sequence of readonly spans of Utf8 bytes in the case of `Utf8JsonReader`), based upon contract information derived from the type using reflection. – dbc Sep 18 '22 at 17:16
  • @dbc the result of `castedObject.GetType()` is `CoreConsoleApp1.ExtendedUserModel` which is exactly what we need. My question is, using that costly serialization and deserialization the only way to achieve this? – wiki Sep 18 '22 at 17:22
  • 1
    *"which after serialization, becomes an object of type `Dictionary`"* I doubt that. I don't think JSON can handle objects as keys ... – derpirscher Sep 18 '22 at 17:22
  • @derpirscher that's the result of using MessagePack not Json libraries. – wiki Sep 18 '22 at 17:24
  • Incidentally, if you know `typeof(ExtendedUserModel)` at the time of deserialization, with Json.NET you can deserialize to a specific `Type` directly by using `JsonConvert.DeserializeObject(string json, Type type)`. See: [Deserialize JSON text to a specific object type using the Type name](https://stackoverflow.com/q/32371532). – dbc Sep 18 '22 at 17:24
  • @dbc as I understand it, OP doesn't want to use JSON at all, but it's just his current workaround for typeconversion – derpirscher Sep 18 '22 at 17:26
  • @derpirscher exactly. that's a hacky and costly workaround. – wiki Sep 18 '22 at 17:26
  • 1
    But in your question, you state *I have a variable of type `ExtendedUserModel` which after serialization, becomes an object of type `Dictionary`*. So at some point you are doing a serialization/deserialization round trip which is how you got the `Dictionary` to begin with, aren't you? If not, can you share a little how the `Dictionary` was initially created? I'm thinking you might have an [xy problem](https://meta.stackexchange.com/q/66377) here and you could create `ExtendedUserModel` without the intermediate dictionary. – dbc Sep 18 '22 at 17:28
  • Well the official way is the one you ruled out. Implementing `IConvertible`. The other (probably hacky ) way is using reflection. But for help on that, you would need to give more information – derpirscher Sep 18 '22 at 17:29
  • @derpirscher the intent of question is to now how is it possible to convert an object (`Dictionary`) to its actual type (`ExtendedUserModel`) when only Type information (`typeof(ExtendedUserModel)`) is available? (Json libraries can do this without the need for `IConvertible`) – wiki Sep 18 '22 at 17:37
  • 1
    As stated by @dbc and myself: The other way is using [Reflection](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/reflection) But without further information from your side nobody will be able to help you ... – derpirscher Sep 18 '22 at 17:57
  • 1
    Assuming you can't restructure your code to deserialize to the final type directly from MessagePack, do any of the solutions from [Mapping object to dictionary and vice versa](https://stackoverflow.com/q/4943817) meet your needs? And, why `Dictionary` rather than `Dictionary`? Can the keys be something other than the property names? – dbc Sep 18 '22 at 18:00
  • 1
    And actually, why can't you deserialize from MessagePack directly to the final type? Is it just that your deserialization code doesn't take a `Type` argument, so you can't pass in `typeof(ExtendedUserModel)`? – dbc Sep 18 '22 at 18:01

0 Answers0