我正在为Minecraft实体定义编写解析器。我在数据中找到了这种惯例,其中像“roll”这样的对象可以这样定义
"rolls": {
"min": 2,
"max": 2
}
但也可以这样定义
"rolls": 1
我正在使用Newtonsoft JSON.net,以防有人知道json.net的方式来做到这一点。我只是不确定是否有一种简单的方法用c#
来表示这种变化答案 0 :(得分:2)
为此,我使用了c#type dynamic
。它使您能够从对象中读取变量,就像它是强类型一样。
在你的情况下..
dynamic myObj = //your JSON deserialize method
//first example (Take note of the array)
int min = myObj.rolls[0].min;
int max = myObj.rolls[0].max;
//your second example
int numRolls = myObj.rolls;
请注意,您将不会获得任何代码建议,但它确实在运行时工作,只要正确反序列化JSON即可。如果在dynamic myObj
行上放置断点,它可以提供帮助,因此您可以准确地看到对象的组成部分。
我不确定它的内存使用/安全可用性,也许有人可以发表评论?
注意 :这是用于一个不断变化且不受我控制的数据结构中,几十个类已经有几十个创造和维护。可能还有更好的方法,但如果您的示例是您将面临的最复杂的结构,那么您最好只创建这两个类并反序列化为正确的结构。
答案 1 :(得分:0)
这需要花费很长时间才能完成,这个解决方案可能不是最优的,但是这段代码确实有用
class RollsConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(Rolls));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
if (token.Type == JTokenType.Object)
{
return token.ToObject<Rolls>();
}
return new Rolls(token.ToObject<Int64>());
}
public override bool CanWrite
{
get { return true; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
JToken t = JToken.FromObject(value);
Rolls rolls = value as Rolls;
if (rolls.Value > 0)
{
writer.WriteValue(rolls.Value);
}
else
{
JObject o = (JObject)t;
o.WriteTo(writer);
}
}
}
public class Rolls
{
public Rolls(Int64 val)
{
Value = val;
}
public static implicit operator Rolls(Int64 value)
{
return new Rolls(value);
}
public bool ShouldSerializeMin()
{
// Only is value is unspecified
return Value == 0;
}
public bool ShouldSerializeMax()
{
// Only is value is unspecified
return Value == 0;
}
public bool ShouldSerializeValue()
{
// Only is value is specified
return Value > 0;
}
[JsonProperty(PropertyName = "min", NullValueHandling = NullValueHandling.Ignore)]
public Int64 Min { get; set; }
[JsonProperty(PropertyName = "max", NullValueHandling = NullValueHandling.Ignore)]
public Int64 Max { get; set; }
[JsonIgnore]
public Int64 Value { get; set; }
}
[JsonProperty(PropertyName = "rolls", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(RollsConverter))]
public Rolls Roll { get; set; }