原来SortedList是根据comparer的比较结果判断插入的键是否重复的...
刚才在做一个使用NHibernate的主从表维护的页面.hibernate的一对多集合一般用Set,一种元素不可重复的集合.由于.Net没有Set,作者先用HashTable或SortedList凑合用着,而集合的类型必须要声明为IDictionary.因为某些原因我必须要对从表数据按Id排序,于是在配置文件加上一个自己写的Comparer.结果程序莫名其妙出错,明明加了两个不同的记录,确会出现"加入了重复的键"的错误.后来经过调试和实验才知道,NHibernate会把可排序的Set实例化成SortedList,而SortedList是通过他的comparer的比较结果判断两个对象是否相同,而不是reference equal.
这是反编译出来的Add方法的代码:
当时我对数据的操作还是在内存中进行,没插入数据库,所以Id还都是0,它就认为有重复键了.
我只好修改comparer的代码了.如果Id都是0,就让比较结果为-1.
...
...
(n天后)
呀,晕了,原来SortedList在初始化时会用个x.CompareTo(x)检查Comparer是否工作正常,所以还是会出错 >_<
解决问题的方法,只能让Set集合 = new HashTable(),然后在Add元素进去.实在没办法让SortedList存在排序结果相同的元素
这是反编译出来的Add方法的代码:
public virtual void Add(object key, object value)
{
if (key == null)
{
throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
}
int i = Array.BinarySearch(keys, 0, _size, key, comparer);
if (i >= 0)
{
throw new ArgumentException(Environment.GetResourceString("Argument_AddingDuplicate__", new object[]{GetKey(i), key}));
}
Insert(~i, key, value);
}
{
if (key == null)
{
throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
}
int i = Array.BinarySearch(keys, 0, _size, key, comparer);
if (i >= 0)
{
throw new ArgumentException(Environment.GetResourceString("Argument_AddingDuplicate__", new object[]{GetKey(i), key}));
}
Insert(~i, key, value);
}
我只好修改comparer的代码了.如果Id都是0,就让比较结果为-1.
...
...
(n天后)
呀,晕了,原来SortedList在初始化时会用个x.CompareTo(x)检查Comparer是否工作正常,所以还是会出错 >_<
解决问题的方法,只能让Set集合 = new HashTable(),然后在Add元素进去.实在没办法让SortedList存在排序结果相同的元素