8

In my code I have objects (and methods) that are working with quite a few IDs that are just simple Integers. To get a bit of help from the compiler when I'm setting values all over the place, I turned these simple ints into more strongly typed objects, kind of type aliases. Something like this:

public struct CustomId
{
    private readonly int id;
    public CustomId(int id) => this.id = id;

    public static implicit operator int(CustomId cid) => cid.id;
    public static implicit operator CustomId(int id) => new CustomId(id);
}

But as it's really just an int with a more specific name, I'd really like to serialize it just as an int so for example in JSON a Person would look like this:

{
    "Name": "ASD",
    "Id": 42 // this would be the serialized result of my CustomId
}

While I managed to build a custom JsonConverter for this case and it works fine if I'm using Newtonsoft JSON, I'm wondering if there is a better way of doing this, an attribute or an interface to implement (something from the System.Runtime.Serialization namespace), that most serializer frameworks will take into consideration, so I wouldn't have to write custom converters for JSON, XML, Protobuf, etc. serialization but could just rely on some generic solution.

Emil
  • 81
  • 2
  • Json.NET will also use a `TypeConverter` to convert from and to a string if present. See [Json.Net: Serialize/Deserialize property as a value, not as an object](https://stackoverflow.com/q/40480489/3744182). I don't think there is a mechanism that works for all serializers however. `XmlSerializer` doesn't support surrogates, for instance. Also, this question might be too broad for stackoverflow. Can you specify the serializer(s) you are using? – dbc May 30 '18 at 21:56
  • And, while the data contract serializers do support surrogates, apparently the surrogate type cannot be a primitive. See [DataContract surrogate for amplified value type](https://stackoverflow.com/q/8072320). – dbc May 30 '18 at 22:02
  • There's not much more specific I can give, it's more of an experiment/research than something too specific. I'm just trying to figure out if there's an easy way to have these "strongly typed primitives" in my code and at the same time when it comes to serialisation treat them as primitives (Integers), in database, JSON/XML/ProtoBuf/binary serialisation scenarios. I only want these types to make MY life easier and have some compiler checking, but not mess up the serialized contract of the objects, so others can still easily treat them as just Integers. – Emil May 30 '18 at 22:32
  • But I guess I will have to write a bunch of converters. – Emil May 30 '18 at 22:33
  • You may not need to write a "bunch" of converters. Use of generics should help a lot here, and depending on the serializers you are using you may be able to share surrogates. For instance you should be able to share a generic surrogate between `XmlSerializer` and `DataContractSerializer` by implementing `IXmlSerializable` -- but this will cause problems if you are using `DataContractJsonSerializer`. So if you can restrict the scope of your question to specific serializers we may be able to give you some help. – dbc May 30 '18 at 23:49
  • My question was if there is a generic way of doing this and the answer is no. You already helped me a lot with this, so now I'll just try to find an elegant way to minimize the code I have to write to support this in whatever scenario I need it. Thank you. – Emil May 31 '18 at 08:40

0 Answers0