【问题标题】:Deserialize string with Tuple key in C#在 C# 中使用元组键反序列化字符串
【发布时间】:2018-02-09 23:37:00
【问题描述】:

我有一本这样的字典:

var dict1 = new Dictionary<(int, int), int);
dict1.add((1,2), 3);

使用以下方法将其序列化为字符串:

var s = JsonConvert.SerializeObject(dict1);
// s = "{\"(1,2)\":\"3\"}";

当尝试反序列化字符串时:

var j = JsonConvert.DeserializeObject<Dictionary<(int, int), int>>(s);

我收到如下错误:

'无法将字符串'(1,2)' 转换为字典键类型'System.ValueTuple`2[System.Int32,System.Int32]'。创建一个 TypeConverter 将字符串转换为键类型对象。

如何将我的字符串反序列化为元组键?使用自定义对象或TypeConverter?如果有,怎么做?

【问题讨论】:

标签: c# .net serialization


【解决方案1】:

首先,你让自己成为 ValueTuples

的 TypeConverter
internal class ValueTupleConverter<T1, T2>
   : TypeConverter 
   where T1: struct where T2: struct
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, 
      Type sourceType)
    {
        return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context,
      CultureInfo culture, object value)
    {
        var elements = ((String)value).Split(new[] { '(', ',', ')'},
          StringSplitOptions.RemoveEmptyEntries);

        return (
            JsonConvert.DeserializeObject<T1>(elements.First()), 
            JsonConvert.DeserializeObject<T2>(elements.Last()));
    }
}

(生产代码应该更加健壮和高效。)

然后,因为你不能在编译时应用 TypeConverter 属性,所以你在运行时添加它,一次

  TypeDescriptor.AddAttributes(typeof((Int32, Int32)), 
    new TypeConverterAttribute(typeof(ValueTupleConverter<Int32, Int32>)));

最后,你照常转换

var j = JsonConvert.DeserializeObject<Dictionary<(int, int), int>>(s);

【讨论】:

  • 很好,将它添加到Program.cs 并进行了一些额外的错误检查,它似乎可以完美地工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 2012-06-11
  • 2012-05-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多