今天遇到一个问题“could not conver string to dictionary key”什么什么的错误
首先我重写了一个Dictionary,让他继承IDictionary
public class MyDictionary : IDictionary<MyClass,double>
{
private List<MyClass> _myClassList;
private List<double> _ratioList;
public MyDictionary()
{
_myClassList = new List<MyClass>();
_ratioList = new List<double>();
}
public ICollection<MyClass> Keys
{
get
{
return _myClassList;
}
}
public ICollection<double> Values
{
get
{
return _ratioList;
}
}
public int Count
{
get
{
return _myClassList.Count;
}
}
public bool IsReadOnly
{
get
{
return false;
}
}
public double this[MyClass key]
{
get
{
return _ratioList[_myClassList.IndexOf(key)];
}
set
{
_ratioList[_myClassList.IndexOf(key)] = value;
}
}
public bool ContainsKey(MyClass key)
{
return _myClassList.Contains(key);
}
public void Add(MyClass key, double value)
{
_myClassList.Add(key);
_ratioList.Add(value);
}
public bool Remove(MyClass key)
{
int index = _myClassList.IndexOf(key);
if (index == -1)
return false;
_myClassList.Remove(key);
_ratioList.RemoveAt(index);
return true;
}
public bool TryGetValue(MyClass key, out double value)
{
int index = _myClassList.IndexOf(key);
if (index == -1)
{
value = 0;
return false;
}
value = _ratioList[index];
return true;
}
public void Add(KeyValuePair<MyClass, double> item)
{
_myClassList.Add(item.Key);
_ratioList.Add(item.Value);
}
public void Clear()
{
_myClassList.Clear();
_ratioList.Clear();
}
public bool Contains(KeyValuePair<MyClass, double> item)
{
return _myClassList.Contains(item.Key) && _ratioList.Contains(item.Value);
}
public void CopyTo(KeyValuePair<MyClass, double>[] array, int arrayIndex)
{
for (int index = 0; index < array.Length; index++)
{
array[index] = new KeyValuePair<MyClass, double>(_myClassList[index + arrayIndex], _ratioList[index + arrayIndex]);
}
}
public bool Remove(KeyValuePair<MyClass, double> item)
{
if (_myClassList.IndexOf(item.Key) == -1)
return false;
_myClassList.Remove(item.Key);
_ratioList.Remove(item.Value);
return true;
}
public IEnumerator<KeyValuePair<MyClass, double>> GetEnumerator()
{
for (int i = 0; i < _myClassList.Count; i++)
{
yield return new KeyValuePair<MyClass, double>(_myClassList[i],_ratioList[i]);
}
}
IEnumerator IEnumerable.GetEnumerator()
{
for (int i = 0; i < _myClassList.Count; i++)
{
yield return _myClassList[i];
}
}
}
这是字典的Key:MyClass类
public class MyClass
{
private MyEnum _myEnum1;
private MyEnum _myEnum2;
public MyClass(MyEnum myEnum1, MyEnum myEnum2)
{
MyEnum1 = myEnum1;
MyEnum2 = myEnum2;
}
/// <summary>
/// 第一个系数
/// </summary>
public MyEnum MyEnum1
{
get { return _myEnum1; }
set { _myEnum1 = value; }
}
/// <summary>
/// 第二个系数
/// </summary>
public MyEnum MyEnum2
{
get { return _myEnum2; }
set { _myEnum2 = value; }
}
public override bool Equals(object obj)
{
if (obj == this)
return true;
if (!(obj is MyClass))
return false;
var dicconfikey = (MyClass)obj;
return MyEnum1 == dicconfikey.MyEnum1 && MyEnum2 == dicconfikey.MyEnum2;
}
public override int GetHashCode()
{
return MyEnum1.GetHashCode() + MyEnum2.GetHashCode();
}
}
然后我发现我的Json文件序列化后是“MyNameSpace.Myclass”:1.0
显示的是类名,无法反序列化,只要重写这个MyClass类的ToString方法就可以了
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
然后再看Json文件是"{\"MyEnum1\":1,\"MyEnum2\":1}":1.0
看看是否可以反序列化。运行发现出错,仍然无法反序列,为什么呢,我猜测应该是出在了我这个字典上了。根据stackoverflow,看来应该只能使用JsonConverter了。
定义一个MyDictionaryConverter
public class MyDictionaryConverter : JsonConverter
{
//是否开启自定义反序列化,值为true时,反序列化时会走ReadJson方法,值为false时,不走ReadJson方法,而是默认的反序列化
public override bool CanRead => true;
//是否开启自定义序列化,值为true时,序列化时会走WriteJson方法,值为false时,不走WriteJson方法,而是默认的序列化
public override bool CanWrite => false;
public override bool CanConvert(Type objectType)
{
return typeof(Mydictionary) == objectType;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
//获取JObject对象,该对象对应着我们要反序列化的json
var jobj = serializer.Deserialize<Newtonsoft.Json.Linq.JObject>(reader);
Mydictionary info = new Mydictionary();
foreach (var pro in jobj.Properties())
{
//调试发现有两个,一个是左边的PATH,实际就是MyClass对象,另一个就是double值。对应到我们Mydictionary就是key跟value
JObject jo = JObject.Parse(pro.Path);
var myEnum1= jo.Value<int>("MyEnum1");
var myEnum2= jo.Value<int>("MyEnum2");
info.Add(new MyClass((MyEnum)myEnum1, (MyEnum)myEnum2), (double)pro.Value);
}
return info;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException("Unnecessary because CanWrite is false.The type will skip the converter.");
}
}
然后在MyDictionary类的定义上面增加个Attribute:[JsonConverter(typeof(MyDictionaryConverter))]