两种类型的变量
Posted
技术标签:
【中文标题】两种类型的变量【英文标题】:A variable of two types 【发布时间】:2016-03-27 12:33:34 【问题描述】:我需要从 TypeScript 中读取一个 JSON 对象,该对象有一个变量名 prop
是两种类型,Identifier
或 Expression
到 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#
是一种强类型语言,没有什么像“”。在某些情况下,您可以使用object
或dynamic
,但它们以后可能会导致其他问题。对于您的情况,您可以创建一个包含两种类型的包装器类型,并从JavaScript
填充所需的一种,但如果没有完整的上下文很难建议。
谢谢,您还能发现哪些其他问题?
所有失去类型安全的东西,比如运行时的类型不匹配。对于JsonConvert.DeserializeObject
,你可以使用dynamic,但不知道类型我猜会很难。
没有“JSON 对象”之类的东西,您能澄清一下Identifier
或Expression
的含义吗?我怀疑其中之一并没有真正遵循 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";
输出:
【讨论】:
谢谢,待我测试方法后再回复你以上是关于两种类型的变量的主要内容,如果未能解决你的问题,请参考以下文章