Json.net c#将对象列表转换为2D数组

本文关键字:转换 2D 数组 列表 对象 net Json | 更新日期: 2023-09-27 18:03:46

是否可以将对象列表从json转换为2D数组?

Data.json

{
    "x": 6,
    "y": 6,
    "information": [
        {
            "x": 0,
            "y": 0,
            "info": "First item",
            "info2": 1
        },
        {
            "x": 1,
            "y": 3,
            "info": "Second item",
            "info2": 3
        },
        {
            "x": 3,
            "y": 4,
            "info": "Third item",
            "info2": 2
        }
    ]
}

第一个x和y是2D数组的大小。是否可以使用自定义JsonConverter将信息列表放入基于信息对象的x和y的数组中?我知道可以先将其转换为列表,然后在没有Json.net的情况下转换为数组,但是在反序列化时可能吗?

Json.net c#将对象列表转换为2D数组

我已经为您创建了一个自定义转换器:

少:

public class Item
{
    [JsonProperty("x")]
    public int X { get; set; }
    [JsonProperty("y")]
    public int Y { get; set; }
    [JsonProperty("info")]
    public string Info { get; set; }
    [JsonProperty("info2")]
    public string Info2 { get; set; }
}

转换器:

public class ItemJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Item[,]);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jObject = JObject.Load(reader);
        var x = jObject.Value<int>("x");
        var y = jObject.Value<int>("y");
        var items = jObject.GetValue("information").ToObject<IEnumerable<Item>>();
        var itemsArray = new Item[x, y];
        foreach (var item in items)
        {
            itemsArray[item.X, item.Y] = item;
        }
        return itemsArray;
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

用法:

var jsonStr = @"{
                    ""x"": 3,
                    ""y"": 1,
                    ""information"": [
                        {
                            ""x"": 0,
                            ""y"": 0,
                            ""info"": ""First item"",
                            ""info2"": 1
                        },
                        {
                            ""x"": 1,
                            ""y"": 0,
                            ""info"": ""Second item"",
                            ""info2"": 3
                        },
                        {
                            ""x"": 2,
                            ""y"": 0,
                            ""info"": ""Third item"",
                            ""info2"": 2
                        }
                    ]
                }";
var jss = new JsonSerializerSettings();
jss.Converters.Add(new ItemJsonConverter());
var obj = JsonConvert.DeserializeObject<Item[,]>(jsonStr, jss);

也许最简单/最快的方法是手动执行,像这样:

using Newtonsoft.Json;
namespace WpfApplication3
{
    public partial class MainWindow
    {
        private readonly string json = @"
{
    ""x"": 6,
    ""y"": 6,
    ""information"": [
        {
            ""x"": 0,
            ""y"": 0,
            ""info"": ""First item"",
            ""info2"": 1
        },
        {
            ""x"": 1,
            ""y"": 3,
            ""info"": ""Second item"",
            ""info2"": 3
        },
        {
            ""x"": 3,
            ""y"": 4,
            ""info"": ""Third item"",
            ""info2"": 2
        }
    ]
}";
        public MainWindow()
        {
            InitializeComponent();
            var o = JsonConvert.DeserializeObject<SampleResponse1>(json);
            var array = new IInformation[o.X, o.Y];
            foreach (var i in o.Information)
            {
                array[i.X, i.Y] = i;
            }
        }
    }
    internal class SampleResponse1
    {
        [JsonProperty("x")]
        public int X { get; set; }
        [JsonProperty("y")]
        public int Y { get; set; }
        [JsonProperty("information")]
        public Information[] Information { get; set; }
    }
    internal class Information : IInformation
    {
        [JsonProperty("x")]
        public int X { get; set; }
        [JsonProperty("y")]
        public int Y { get; set; }
        #region IInformation Members
        [JsonProperty("info")]
        public string Info { get; set; }
        [JsonProperty("info2")]
        public int Info2 { get; set; }
        #endregion
    }
    internal interface IInformation
    {
        string Info { get; set; }
        int Info2 { get; set; }
    }
}

请注意,我并没有真正麻烦,只是使用了一个接口来隐藏 xy,请随意进一步调整它。

另外,我使用http://jsonclassgenerator.codeplex.com/转换为类