Q: Two fields in a class with the same Json PropertyName What would be the best approach for having a class with two distinct fields (with distinct types) but same PropertyName.
It will always be the case that whenever one of the fields has a value, the other one will be null. I know I could create
two different classes, each of them with only one field. Is there a better alternative than creating two different classes?
Here's an example of what I'm trying to accomplish:
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class Foo
{
    private Foo(int x, bool asAList = false)
    {
        if (asAList)
        {
            Baz = new List<int> { x };
        }
        else
        {
            Bar = x;
        }
    }

    public static JObject Get(int x, bool asAList = false)
    {
        Foo foo = new Foo(x, asAList);
        return JObject.FromObject(foo);
    }

    [JsonProperty(PropertyName = "qwerty", NullValueHandling = NullValueHandling.Ignore)]
    public int? Bar { get; set; } = null;

    [JsonProperty(PropertyName = "qwerty", NullValueHandling = NullValueHandling.Ignore)]
    public List<int> Baz { get; set; } = null;
}

And I'd like to be able to do this:
JObject a = Foo.Get(1);
JObject b = Foo.Get(2, true);


A: You could have one private JToken JsonProperty that is being used for serializing/deserializing to either of the two public facing properties.  On a set operation, that would then determine based on the JToken type if it's a JArray or not and then based on that determine which of the other properties to set.  On a get operation, it would use the property that isn't null and convert that to the JToken.  In order to deserialize you'll want a constructor that can be used the [JsonConstructor] can be added.  Since you don't want to serialize/deserialize the other properties directly, the [JsonProperty] attribute can be removed because of the MemberSerialization.OptIn. 
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class Foo
{
    [JsonConstructor]
    private Foo()
    { }

    private Foo(int x, bool asAList = false)
    {
        if (asAList)
            Baz = new List<int> { x };
        else
            Bar = x;
    }

    public static JObject Get(int x, bool asAList = false)
    {
        Foo foo = new Foo(x, asAList);
        return JObject.FromObject(foo);
    }

    [JsonProperty(PropertyName = "qwerty", NullValueHandling = NullValueHandling.Ignore)]
    private JToken Qwerty
    {
        get
        {
            return Bar.HasValue ? JToken.FromObject(Bar) : Baz != null ? JToken.FromObject(Baz) : null;
        }
        set
        {
            if (value != null && value.Type == JTokenType.Array)
                Baz = value?.ToObject<List<int>>();
            else
                Bar = value?.ToObject<int?>();
        }
    }

    public int? Bar { get; set; }

    public List<int> Baz { get; set; }
}

