Estou procurando uma classe de dicionário genérica e bidirecional 1 para 1 em C # (2), ou seja, umaBiDictionaryOneToOne<T, S>
que tem a garantia de conter apenas um de cada valor e chave (até RefEquals de qualquer maneira) e que pode ser pesquisado usando a chave ou o valor. Alguém conhece um ou devo implementá-lo sozinho? Não acredito que sou a primeira pessoa a precisar disso ...
Há um BiDictionary nas respostas a esta pergunta , mas não é para elementos exclusivos (e também não implementa RemoveByFirst (T t) ou RemoveBySecond (S s)).
Obrigado!
c#
.net
collections
Joel in Gö
fonte
fonte
Respostas:
OK, aqui está a minha tentativa (baseada na de Jon - obrigado), arquivada aqui e aberta para melhorias:
fonte
Uma implementação mais completa de dicionário bidirecional:
Dictionary<TKey,TValue>
(exceto interfaces de infraestrutura):IDictionary<TKey, TValue>
IReadOnlyDictionary<TKey, TValue>
IDictionary
ICollection<KeyValuePair<TKey, TValue>>
(esta e abaixo são as interfaces básicas das acima)ICollection
IReadOnlyCollection<KeyValuePair<TKey, TValue>>
IEnumerable<KeyValuePair<TKey, TValue>>
IEnumerable
SerializableAttribute
.DebuggerDisplayAttribute
(com informações de contagem) eDebuggerTypeProxyAttribute
(para exibir pares de valores-chave em relógios).IDictionary<TValue, TKey> Reverse
propriedade e também implementa todas as interfaces mencionadas acima. Todas as operações em qualquer um dos dicionários modificam ambos.Uso:
O código está disponível em minha estrutura privada no GitHub: BiDictionary (TFirst, TSecond) .cs ( permalink , pesquisa ).
Cópia de:
fonte
item.Reverse
linhas. Algum requisito específico de versão?KeyValuePairExts
classe na parte inferior do trecho de código.A pergunta à qual você se refere também mostra uma implementação individual nesta resposta . Adicionar RemoveByFirst e RemoveBySecond seria trivial - assim como implementar interfaces extras etc.
fonte
Essa é a mesma resposta aceita, mas também forneci
Update
métodos e, principalmente, um pouco mais de detalhes:Semelhante à minha resposta aqui
Algumas coisas a serem observadas:
Eu implementei apenas
IEnumerable<>
. Não acho queICollection<>
faça sentido aqui, uma vez que todos os nomes dos métodos podem ser muito diferentes para essa estrutura de coleção especial. Cabe a você decidir o que deve entrarIEnumerable<>
. Então agora você tem a sintaxe do inicializador de coleção também, comoEu tentei que algumas exceções estranhas fossem lançadas aqui e ali - apenas para integridade de dados. Só para ficar do lado mais seguro para que você saiba se algum dia meu código tem bugs.
Desempenho: Você pode pesquisar
Value
com qualquer um dosKeys
, o que significaGet
eContains
método requerem apenas 1 pesquisa (O (1)).Add
requer 2 pesquisas e 2 adições.Update
requer 1 pesquisa e 2 adições.Remove
leva 3 pesquisas. Todas semelhantes à resposta aceita.fonte
IEnumerator<Tuple<TKey1, TKey2>>
aqui. NãoIEnumerator<KeyValuePair<TKey1, TKey2>>
, então acho que não posso fazer isso com minha função GetEnumerator. Eu entendi corretamente?Eu criei essa classe, usando classes de coleção C5.
fonte
Outra extensão da resposta aceita. Ele implementa IEnumerable para que seja possível usar foreach com isso. Sei que há mais respostas com a implementação de IEnumerable, mas esta usa structs, portanto, é amigável para o coletor de lixo . Isso é especialmente útil no mecanismo Unity (verificado com o profiler).
fonte
Um pouco tarde, mas aqui está uma implementação que escrevi um tempo atrás. Ele lida com alguns casos extremos interessantes, como quando a chave substitui a verificação de igualdade para executar a igualdade parcial. Isso resulta no armazenamento do dicionário principal,
A => 1
mas no armazenamento inverso1 => A'
.Você acessa o dicionário inverso por meio da
Inverse
propriedade.Fonte original e testes no github.
fonte