问题
I have a dictionary like this:
var dict1 = new Dictionary<(int, int), int);
dict1.add((1,2), 3);
That is serialized to a string using:
var s = JsonConvert.SerializeObject(dict1);
// s = "{\"(1,2)\":\"3\"}";
When trying to deserialize the string using:
var j = JsonConvert.DeserializeObject<Dictionary<(int, int), int>>(s);
I get an error like:
'Could not convert string '(1,2)' to dictionary key type 'System.ValueTuple`2[System.Int32,System.Int32]'. Create a TypeConverter to convert from the string to the key type object.
How can I deserialize my string into a tuple key? Using a custom object or a TypeConverter
? If so, how?
回答1:
First, you make yourself a TypeConverter for ValueTuples<T1,T2>
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()));
}
}
(Production code should be made more robust and efficient.)
Then, because you can't do the usual thing of applying the TypeConverter attribute at compile-time, you add it at run-time, once
TypeDescriptor.AddAttributes(typeof((Int32, Int32)),
new TypeConverterAttribute(typeof(ValueTupleConverter<Int32, Int32>)));
Finally, you convert as you were doing
var j = JsonConvert.DeserializeObject<Dictionary<(int, int), int>>(s);
来源:https://stackoverflow.com/questions/48715635/deserialize-string-with-tuple-key-in-c-sharp