Quando a exceção não é uma opção, vá para Pesquisa
Se você está tentando obter uma estrutura tão eficiente quanto uma, Dictionarymas não sabe ao certo que não há chave duplicada na entrada, Lookupé mais seguro.
Como mencionado em outra resposta, ele também suporta chaves nulas e retorna sempre um resultado válido quando consultado com dados arbitrários; portanto, ele parece mais resiliente a entradas desconhecidas (menos propenso que o Dictionary a gerar exceções).
E é especialmente verdade se você comparar com a System.Linq.Enumerable.ToDictionaryfunção:
// won't throw
new[] { 1, 1 }.ToLookup(x => x);
// System.ArgumentException: An item with the same key has already been added.
new[] { 1, 1 }.ToDictionary(x => x);
A alternativa seria escrever seu próprio código de gerenciamento de chaves duplicado dentro de um foreachloop.
Considerações sobre desempenho, Dicionário: um vencedor claro
Se você não precisar de uma lista e gerenciar um grande número de itens, Dictionary(ou mesmo sua própria estrutura personalizada) seria mais eficiente:
Stopwatch stopwatch = new Stopwatch();
var list = new List<string>();
for (int i = 0; i < 5000000; ++i)
{
list.Add(i.ToString());
}
stopwatch.Start();
var lookup = list.ToLookup(x => x);
stopwatch.Stop();
Console.WriteLine("Creation: " + stopwatch.Elapsed);
// ... Same but for ToDictionary
var lookup = list.ToDictionary(x => x);
// ...
Como Lookupé necessário manter uma lista de itens para cada chave, é mais lento que o Dicionário (cerca de 3x mais lento para um grande número de itens)
Velocidade de pesquisa: Criação: 00: 00: 01.5760444
Velocidade do dicionário: Criação: 00: 00: 00.4418833