如何定义一个C#类以表示可以在其实现中变化的JSON对象



我正在为《我的世界》实体定义写一个解析器。我在数据中发现了这个约定,其中可以以这种方式定义"滚动"之类的对象

"rolls": {
    "min": 2,
    "max": 2
 }

,但也可能会以这种方式定义

  "rolls": 1

我正在使用newtonsoft json.net,以防任何人知道json.net做到这一点。我只是不确定是否有一种简单的方法可以用C#

表示这种变化。

我为此使用了C#类型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行上放置断点,可以帮助您确切地看到该对象的组成。

我不确定它的内存使用/安全可用性,也许有人可以发表评论?

Note :这是用于在不断变化和无法控制的数据结构中使用的,在数十个类中可以创建和维护会有数十个。可能还有一种更好的方法,但是如果您的示例是您要面对的最复杂的结构,那么最好只创建这两个类,然后对正确的结构进行挑选。

这花费了很长时间才能实现,并且该解决方案可能不是最佳的,但是此代码确实有效

        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; }

相关内容

  • 没有找到相关文章

最新更新