泛型的 JSON 序列化

Mat*_*and 6 c# generics serialization json.net

我有一堂课,看起来像这样:

public class MyData : IList<Tuple<double,double>>
Run Code Online (Sandbox Code Playgroud)

这个想法是你有一个值对列表。够简单的。但我希望将其序列化,使其看起来像双精度数组的数组(即double[][]),而不是元组列表。序列化后应该如下所示:

[[1,1],[2,2],[3,3]]
Run Code Online (Sandbox Code Playgroud)

所以我创建了一个简单的JsonConverter可以做到这一点。它有一个非常简单的WriteJson方法,如下所示:

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    var obj = value as MyData;
    double[][] dataArray = (from dp in obj._data
                            select new[] { dp.Item1, dp.Item2 }).ToArray();
    var ser = new JsonSerializer();
    ser.Serialize(writer, dataArray);
}
Run Code Online (Sandbox Code Playgroud)

MyData用适当的属性进行装饰:

    [JsonConverter(typeof(MyDataJsonConverter))]
    public class MyData: IList<Tuple<double,double>>
Run Code Online (Sandbox Code Playgroud)

一切都很好。然而现在,我想扩展它并使其MyData通用:

    public class MyData<S,T>: IList<Tuple<S,T>>
Run Code Online (Sandbox Code Playgroud)

这就是我遇到问题的地方。最初,我尝试MyDataJsonConverter也通用:

   [JsonConverter(typeof(MyDataJsonConverter<S,T>))]
   public class MyData<S,T>: IList<Tuple<S,T>>
Run Code Online (Sandbox Code Playgroud)

但这是不允许的,因为您不能将泛型与属性一起使用。

所以我必须保持MyDataJsonConverter非通用性,但我需要弄清楚如何将我的元组集合展平为数组(大概是现在object[][]),这样当我序列化我的数据时,它看起来像:

[[1,2],[2,3]]
Run Code Online (Sandbox Code Playgroud)

或者:

[["foo":1],["bar":2]]
Run Code Online (Sandbox Code Playgroud)

甚至:

[["foo":"bar"],["what":"ever"]]
Run Code Online (Sandbox Code Playgroud)

关于如何处理它有什么想法吗?在 中WriteJson,我无法再强制转换valueMyData,因为我不知道类型参数,因此此时一切都几乎崩溃了。

我可以为每种类型组合创建单独的类(所以一个用于Tuple<double,double>,一个用于Tuple<string,double>等等......),但我想知道在我对其进行暴力处理之前是否有更好的方法。

Mat*_*and 3

好的,这基本上就是我最终所做的(以防其他人需要类似的东西)。我的收藏看起来像这样:

    [JsonConverter(typeof(MyDataJsonConverter))]
    public class MyData<S,T> : IList<Tuple<S,T>>
    {
        private List<Tuple<S, T>> _data;
        // all the implementation of IList...
    }
Run Code Online (Sandbox Code Playgroud)

我的自定义转换器(现在不再嵌套在内部MyData)如下所示:

internal class MyDataJsonConverter : JsonConverter
{

    public override bool CanConvert(Type objectType)
    {
        return objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(MyData<,>);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        // Note: this is strictly for serializing, deserializing is a whole other
        // ball of wax that I don't currently need!
        throw new NotImplementedException();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var obj = value as IEnumerable<dynamic>;
        object[][] dataArray = (from dp in obj
                                select new object[] { dp.Item1, dp.Item2 }).ToArray();
        var ser = new JsonSerializer();
        ser.Serialize(writer, dataArray);
    }

    public override bool CanRead
    {
        get
        {
            return false;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)