Ответ 1
Получить дубликаты ключей:
var duplicateKeys =
myCollection
.GroupBy(k => k.Key)
.Where(g => g.Count() > 1)
.Select(g => g.Key);
Я создаю объект 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
в ваш словарь, вы можете полностью избежать этой ошибки с помощью метода LINQ Distinct
до вызова ToDictionary
.
var dict = myCollection.Distinct().ToDictionary(x => x.Key);
Конечно, вышесказанное будет работать только в том случае, если классы в вашей коллекции переопределяют Equals
и GetHashCode
таким образом, который учитывает только свойство Key
. Если это не так, вам нужно создать пользовательский 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);
}
}
ArgumentException
, вызываемый вызовом Dictionary.Add
, не содержит значения ключа. Вы могли бы легко добавить записи в словарь самостоятельно и сделать отдельную проверку заранее:
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);
}
}
Эта дополнительная проверка должна быть довольно недорогой, потому что элементы хранятся хешем.