我写一个将List<int> list,转化为字典的的时候,发现个奇葩现象。
这是个转字典的方法,就是将 x/10的结果作为键,x本身作为值进行存储。
public static Dictionary<int, List<int>> TransToDic(this List<int> self)
{
Dictionary<int, List<int>> result = NewDic();
if (self.Count > 0)
{
for (int i = 0; i < self.Count; i++)
{
int card = self;
int cardrealnum = card / 10;
if (!result.ContainsKey(cardrealnum))
{
result.Add(cardrealnum,NewList());
}
result[cardrealnum].Add(card);
Log.Debug($"取DIC: {cardrealnum} {result[cardrealnum].ListToString()} {result[cardrealnum].GetHashCode()}");
}
}
else result.Clear();
return result;
}
其中的NewDic和NewList方法,是使用了对象池:
public static Dictionary<int, List<int>> NewDic()
{
Dictionary<int, List<int>> result = ObjectPool.Instance.Fetch<Dictionary<int, List<int>>>();
if (result ≠ null && result.Count > 0)
{
foreach (var list in result.Values)
{
list.RecycleList();
}
}
result.Clear();
return result;
}
public static List<int> NewList()
{
List<int> result = ObjectPool.Instance.Fetch<List<int>>();
result.Clear();
return result;
}
在最终的日志里,发现非常奇怪的现象:
也就是说在使用对象池创建NewList的时候,系统在取22的键时,将已经用在字典里的list,重新用上了,所以覆盖了之前取值14、16键的那个list,因为明显哈希值是相同的。
问题是存在这个字典里的list,明明已经是被引用的,为什么还会在对象池里被取出来?上述TransToDic的方法,是同步的,而且系统里没有其他异步关于此字典的访问和操作。