1

I have a class that is implicitly convertible from a string and explicitly convertible from a string. It is not a string, though, and I don't want to replace locations in code with a string, just for the sake of convenience.

When I want to serialize or deserialize an object containing a property that uses this type, I want it to be treated like a string. I know, I could just write a converter (in my case a Json.NET converter), but I would prefer the serialization to be implicit and without any attribute decorations when defining a property of this type.

Is there a possibility to make it easy for the serializer and just get a string from the class when serializing and create an object of the class with the string value inside when deserializing?

This is the code of the class:

public class StringClass
{
    private string value;

    public StringClass(string s)
    {
        Validate(s);
        value = s;
    }

    private void Validate(string value)
    {
        // Some validation happening here, throwing an exception if the input does not match
    }

    public static implicit operator StringClass(string s) => new(s);

    public static explicit operator string(StringClass sc) => sc.value;

    public override int GetHashCode() => value.GetHashCode();

    public override string ToString() => value;
}

An example for a class where this is in use:

C#

public class TestClass
{
    public StringClass Id { get; set; }
    
    public string Name { get; set; }
}

Json

{
    "id": "123456789abcdef",
    "name": "username"
}

Things I thought about doing:

  1. Implementing the ISerializable interface. But I think this works only when serializing, not when deserializing.
  2. Writing a converter but instead of applying it to the property, apply it to the class itself somehow (if that's possible).

I am totally fine with "there is no other option, write a converter that needs to be applied to the property", but I want to know if there is an alternative that allows me to omit the whole attribute-on-property-thing and just make it implicit.

Max Play
  • 3,717
  • 1
  • 22
  • 39
  • 1. [ISerializable](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.serialization.iserializable?view=net-5.0), see the example. It serialize and deserialize. – vernou Jun 28 '21 at 10:33
  • 1
    2. You can add the converter in serializer's settings (no need decoration or attribute). – vernou Jun 28 '21 at 10:36
  • Ah, thanks, I totally forgot the second one! And I never used ISerializable, I didn't know it works both ways. Perfect, thanks! – Max Play Jun 28 '21 at 11:40
  • 1
    `ISerializable` lets you serialize your class with manually created key/value pairs, but you want to serialize it as a simple string, so I don't think that will work. Since you mention using Json.NET, see [Json.Net: Serialize/Deserialize property as a value, not as an object](https://stackoverflow.com/q/40480489/3744182). One way or another you will need a `JsonConverter` or `TypeConverter`, Json.NET won't pick up the implicit operator. – dbc Jun 28 '21 at 18:49
  • Or I suppose if you really wanted to you could create a custom contract resolver that picks up on the implicit conversions from and to string, and applies an appropriate converter. Is that what you want? – dbc Jun 28 '21 at 18:54
  • So far I managed to do it using a converter and applying it to the class itself. I didn't know that was possible. – Max Play Jun 29 '21 at 07:31
  • @MaxPlay - is that good enough then? If so shall we close this off as a duplicate of [Json.Net: Serialize/Deserialize property as a value, not as an object](https://stackoverflow.com/q/40480489/3744182)? – dbc Jun 29 '21 at 15:11
  • @dbc Sure, it's basically a duplicate of the linked question. – Max Play Jun 29 '21 at 16:05

0 Answers0