Melhor implementação para estrutura de dados de par de valores-chave?
-
08-06-2019 - |
Pergunta
Ultimamente, tenho mexido um pouco com C# e todas as coleções genéricas me deixaram um pouco confuso.Digamos que eu queira representar uma estrutura de dados em que o topo de uma árvore seja um par de valores-chave e haja uma lista opcional de pares de valores-chave abaixo disso (mas não mais níveis do que esses).Isso seria adequado?
public class TokenTree
{
public TokenTree()
{
/* I must admit to not fully understanding this,
* I got it from msdn. As far as I can tell, IDictionary is an
* interface, and Dictionary is the default implementation of
* that interface, right?
*/
SubPairs = new Dictionary<string, string>();
}
public string Key;
public string Value;
public IDictionary<string, string> SubPairs;
}
Na verdade, é apenas um simples desvio para transmitir dados.
Solução
Existe um tipo de dados real chamado KeyValuePair, use assim
KeyValuePair<string, string> myKeyValuePair = new KeyValuePair<string,string>("defaultkey", "defaultvalue");
Outras dicas
Uma coisa possível que você pode fazer é usar o objeto Dictionary direto da caixa e, em seguida, estendê-lo com suas próprias modificações:
public class TokenTree : Dictionary<string, string>
{
public IDictionary<string, string> SubPairs;
}
Isso lhe dá a vantagem de não precisar impor as regras do IDictionary para sua chave (por exemplo, exclusividade da chave, etc.).
E sim, você acertou o conceito do construtor :)
Acho que o que você deseja (como uma implementação literal da sua pergunta) é:
public class TokenTree
{
public TokenTree()
{
tree = new Dictionary<string, IDictionary<string,string>>();
}
IDictionary<string, IDictionary<string, string>> tree;
}
Na verdade, você disse uma "lista" de valores-chave em sua pergunta, então talvez você queira trocar o interno IDictionary
com um:
IList<KeyValuePair<string, string>>
Existe um tipo interno KeyValuePair.Na verdade, é a isso que o IDictionary lhe dá acesso quando você itera nele.
Além disso, esta estrutura dificilmente é uma árvore, encontrar um nome mais representativo pode ser um bom exercício.
Apenas uma coisa a acrescentar (embora eu ache que sua pergunta já foi respondida por outras pessoas).No interesse da extensibilidade (já que todos sabemos que isso acontecerá em algum momento), você pode querer verificar o Padrão Composto Isso é ideal para trabalhar com "estruturas semelhantes a árvores".
Como eu disse, sei que você está esperando apenas um subnível, mas isso pode ser realmente útil se você precisar estender ^_^ posteriormente
@Jay Mooney:Uma classe de dicionário genérica em .NET é na verdade uma tabela hash, apenas com tipos fixos.
O código que você mostrou não deve convencer ninguém a usar Hashtable em vez de Dictionary, já que ambas as partes do código podem ser usadas para ambos os tipos.
Para tabela hash:
foreach(object key in h.keys)
{
string keyAsString = key.ToString(); // btw, this is unnecessary
string valAsString = h[key].ToString();
System.Diagnostics.Debug.WriteLine(keyAsString + " " + valAsString);
}
Para dicionário:
foreach(string key in d.keys)
{
string valAsString = d[key].ToString();
System.Diagnostics.Debug.WriteLine(key + " " + valAsString);
}
E o mesmo para o outro com KeyValuePair, basta usar a versão não genérica para Hashtable e a versão genérica para Dicionário.
Portanto, é igualmente fácil nos dois sentidos, mas Hashtable usa Object para chave e valor, o que significa que você colocará todos os tipos de valor na caixa e não terá segurança de tipo, e o Dicionário usa tipos genéricos e, portanto, é melhor.
Classe de dicionário é exatamente o que você quer, correto.
Você pode declarar o campo diretamente como Dicionário, em vez de IDictionary, mas isso depende de você.
Use algo assim:
class Tree < T > : Dictionary < T, IList< Tree < T > > >
{
}
É feio, mas acho que vai te dar o que você quer.Pena que KeyValuePair está selado.