A variable of two types

。_饼干妹妹 提交于 2019-12-24 14:07:04

问题


I need to read an JSON object from TypeScript, which has a variable names prop which of two types, either Identifier or Expression to C#. TypeScript can have a variable with multiple types (with its union type feature), e.g., prop is defined as

var property:Identifier | Expression

I am reading the JSON object string from C# with JsonConvert.DeserializeObject, e.g.,

Object facebookFriends = new JavaScriptSerializer().Deserialize<Object>(JSON_Object);

How should I declare a variable of two types in C#? Or should I just use object (i.e., declare as Object property)?


回答1:


If the property can have either of these two formats:

{ "prop": "identifier" }
{ "prop": { "complex": "object" } }

ie. either a simple string or a more complex object you can solve this by using dynamic to accept the parsed prop value, and extra properties to return either the identifier or the complex object. Here is a LINQPad program that demonstrates:

void Main()
{
    var jsonStrings = new[]
    {
        "{ \"prop\": \"identifier\" }",
        "{ \"prop\": { \"complex\": \"object\" } }"
    };

    jsonStrings.Select(json => JsonConvert.DeserializeObject<Test>(json)).Dump();
}

public class Test
{
    public Test()
    {
        _Complex = new Lazy<Complex>(GetComplex);
    }

    [JsonProperty("prop")]
    public dynamic prop { get; set; }

    [JsonIgnore]
    public string Identifier => prop as string;

    private readonly Lazy<Complex> _Complex;

    [JsonIgnore]
    public Complex Complex => _Complex.Value;

    private Complex GetComplex()
    {
        if (!(prop is JObject))
            return null;

        return ((JObject)prop).ToObject<Complex>();
    }
}

public class Complex
{
    public string complex { get; set; }
}

Output:

A different approach would be to create your own types to handle the multiple outputs and again use a secondary property to evaluate what you actually got from the json:

void Main()
{
    var jsonStrings = new[]
    {
        "{ \"prop\": \"identifier\" }",
        "{ \"prop\": { \"complex\": \"object\" } }"
    };

    jsonStrings.Select(json => JsonConvert.DeserializeObject<Test>(json)).Dump();
}

public class Test
{
    [JsonProperty("prop")]
    public dynamic prop { get; set; }

    [JsonIgnore]
    public PropertyValue Property
    {
        get
        {
            if (prop is string)
                return new IdentifierProperty(prop as string);
            return new ExpressionProperty(((JObject)prop).ToObject<Expression>());
        }
    }
}

public abstract class PropertyValue
{
}

public class IdentifierProperty : PropertyValue
{
    public IdentifierProperty(string identifier)
    {
        Identifier = identifier;
    }

    public string Identifier { get; }

    public override string ToString() => Identifier;
}

public class ExpressionProperty : PropertyValue
{
    public ExpressionProperty(Expression expression)
    {
        Expression = expression;
    }

    public Expression Expression { get; }

    public override string ToString() => Expression.ToString();
}

public class Expression
{
    public string complex { get; set; }

    public override string ToString() => $"complex: {complex}";
}

Output:



来源:https://stackoverflow.com/questions/34395609/a-variable-of-two-types

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!