自定义dictionary类的序列化

今天遇到一个问题“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))]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值