如何获得ToDictionary()处理失败的重复键?
本文关键字:失败 处理 何获得 ToDictionary | 更新日期: 2023-09-27 17:49:33
我正在创建一个Dictionary对象,使用IEnumerable
的ToDictionary()
扩展方法:
var dictionary = new Dictionary<string, MyType>
(myCollection.ToDictionary<MyType, string>(k => k.Key));
执行时,抛出以下ArgumentException
:
已添加具有相同键的项。
我如何让它告诉我重复键是什么?
获取重复密钥:
var duplicateKeys =
myCollection
.GroupBy(k => k.Key)
.Where(g => g.Count() > 1)
.Select(g => g.Key);
如果您的特定情况允许只将一组具有重复Key
属性的对象中的一个插入到您的字典中,您可以通过在调用ToDictionary
之前使用LINQ Distinct
方法完全避免此错误。
var dict = myCollection.Distinct().ToDictionary(x => x.Key);
当然,只有当你的集合中的类以一种只考虑Key
属性的方式覆盖Equals
和GetHashCode
时,上述方法才会起作用。如果不是这样,您需要创建一个自定义的IEqualityComparer<YourClass>
,它只比较Key
属性。
var comparer = new MyClassKeyComparer();
var dict = myCollection.Distinct(comparer).ToDictionary(x => x.Key);
如果您需要确保集合中的所有实例最终都在字典中,那么使用Distinct
将不适合您。
不包含失败的键,因为泛型字典不能保证键类型上有一个有意义的ToString方法。您可以创建一个抛出更多信息异常的包装器类。例如:
//Don't want to declare the key as type K because I assume _inner will be a Dictionary<string, V>
//public void Add(K key, V value)
//
public void Add(string key, V value)
{
try
{
_inner.Add(key, value);
}
catch (ArgumentException e)
{
throw new ArgumentException("Exception adding key '" + key + "'", e);
}
}
调用Dictionary.Add
抛出的ArgumentException
不包含键值。您可以自己很容易地将条目添加到字典中,并事先进行明确的检查:
var dictionary = new Dictionary<string, MyType>();
foreach (var item in myCollection)
{
string key = item.Key;
if (dictionary.ContainsKey(key))
{
// Handle error
Debug.Fail(string.Format("Found duplicate key: {0}", key));
}
else
{
dictionary.Add(key, item);
}
}
这个额外的检查应该相当便宜,因为元素是通过散列存储的。