两种类型的变量

Posted

技术标签:

【中文标题】两种类型的变量【英文标题】:A variable of two types 【发布时间】:2016-03-27 12:33:34 【问题描述】:

我需要从 TypeScript 中读取一个 JSON 对象,该对象有一个变量名 prop 是两种类型,IdentifierExpression 到 C#。 TypeScript 可以有一个具有多种类型的变量(具有联合类型特性),例如,prop 被定义为

var property:Identifier | Expression

我正在使用 JsonConvert.DeserializeObject 从 C# 读取 JSON 对象字符串,例如,

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

我应该如何在 C# 中声明?还是我应该只使用object(即声明为Object property)?

【问题讨论】:

当您执行JsonConvert.DeserializeObject 时,您将需要对象的实际type。而且总的来说,C# 是一种强类型语言,没有什么像“”。在某些情况下,您可以使用objectdynamic,但它们以后可能会导致其他问题。对于您的情况,您可以创建一个包含两种类型的包装器类型,并从JavaScript 填充所需的一种,但如果没有完整的上下文很难建议。 谢谢,您还能发现哪些其他问题? 所有失去类型安全的东西,比如运行时的类型不匹配。对于JsonConvert.DeserializeObject,你可以使用dynamic,但不知道类型我猜会很难。 没有“JSON 对象”之类的东西,您能澄清一下IdentifierExpression 的含义吗?我怀疑其中之一并没有真正遵循 JSON 语法。你能举出两者的例子吗? 【参考方案1】:

如果属性可以有以下两种格式之一:

 "prop": "identifier" 
 "prop":  "complex": "object"  

即。无论是简单的字符串还是更复杂的对象,您都可以通过使用 dynamic 接受解析后的 prop 值以及返回标识符或复杂对象的额外属性来解决此问题。这是一个LINQPad 程序,演示:

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; 

输出:

另一种方法是创建您自己的类型来处理多个输出,并再次使用辅助属性来评估您从 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";

输出:

【讨论】:

谢谢,待我测试方法后再回复你

以上是关于两种类型的变量的主要内容,如果未能解决你的问题,请参考以下文章

变量的两种不同类型

如何在 C 中检查变量是不是属于某种类型(比较两种类型)?

go两种数据类型的区别数据类型和操作符常量变量声明

java变量类型都有哪些?各自特点?

声明具有两种类型的变量:“int char”

在java中如何判断一个变量的类型