2008-08-12 10 views
69

Así que he estado hurgando un poco con C# últimamente, y todas las colecciones genéricas me tienen un poco confundido. Digamos que quería representar una estructura de datos donde el jefe de un árbol era un par de valores clave, y luego hay una lista opcional de pares clave de valores debajo de eso (pero no más niveles que estos). ¿Sería esto adecuado?¿Mejor implementación para la estructura de datos del par de valores clave?

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; 
} 

Es solo una simple derivación para pasar datos.

Respuesta

132

Hay un tipo de datos real se llama KeyValuePair, utilice como esto

KeyValuePair<string, string> myKeyValuePair = new KeyValuePair<string,string>("defaultkey", "defaultvalue"); 
+1

Esto funciona muy bien con una instrucción "using" (similar al typedef antiguo) para ahorrar algo de tipeo y hacer todo más claro. Si usa constantemente e. gramo. el par (cuerda, cuerda) –

+8

KeyValuePair NAME_HERE = new KeyValuePair ("defaultkey", "defaultvalue"); – HasanAboShally

+1

Para expandir el comentario de @AndreasReiff: 'using NameValuePair = System.Collections.Generic.KeyValuePair ;' cerca de la parte superior de cada archivo que necesita una estructura '(string, string)'. Aunque me pareció más conveniente crear una 'clase NameValuePair' en mi espacio de nombres:' public class NameValuePair \t { \t \t KeyValuePair it; \t \t NameValuePair pública (nombre de la cadena, cadena de valor) \t \t { \t \t \t it = nueva KeyValuePair (nombre, valor); \t \t} \t \t cadena pública Nombre {get {return it.Key; }} \t \t cadena pública Valor {get {return it.Value; }} \t} ' – ToolmakerSteve

1

Dictionary Class es exactamente lo que quiere, correcta.

Puede declarar el campo directamente como Dictionary, en lugar de IDictionary, pero eso depende de usted.

5

Hay un tipo incorporado KeyValuePair. De hecho, esto es a lo que IDictionary le da acceso cuando itera en él.

Además, esta estructura no es un árbol, encontrar un nombre más representativo podría ser un buen ejercicio.

12

Una cosa posible que podría hacer es utilizar el objeto diccionario en línea recta de la caja y luego simplemente ampliarlo con sus propias modificaciones:

public class TokenTree : Dictionary<string, string> 
{ 
    public IDictionary<string, string> SubPairs; 
} 

Esto le da la ventaja de no tener que cumplir las reglas de IDictionary para su clave (por ejemplo, unicidad de clave, etc.).

Y yup que tienes el concepto del constructor derecho :)

2

@Jay Mooney: en .NET Una clase genérica diccionario es en realidad una tabla hash, sólo con tipos fijos.

El código que ha mostrado no debe convencer a nadie de usar Hashtable en lugar de Dictionary, ya que ambos fragmentos de código se pueden usar para ambos tipos.

Para tabla 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); 
} 

Por diccionario:

foreach(string key in d.keys) 
{ 
    string valAsString = d[key].ToString(); 

    System.Diagnostics.Debug.WriteLine(key + " " + valAsString); 
} 

Y lo mismo para el otro con KeyValuePair, sólo tiene que utilizar la versión no genérica de Hashtable, y la versión genérica de Diccionario.

Así que es igual de fácil en ambos sentidos, pero Hashtable usa Object para clave y valor, lo que significa que va a encapsular todos los tipos de valor, y no tiene seguridad de tipo, y Dictionary utiliza tipos genéricos y es así mejor.

1

usar algo como esto:

class Tree <T> : Dictionary < T, IList< Tree <T> > > 
{ 
} 

Es feo, pero creo que le dará lo que quiere. Lástima que KeyValuePair esté sellado.

3

Solo una cosa para agregar a esto (aunque creo que ya le han respondido otras preguntas).En aras de la extensibilidad (ya que todos sabemos que sucederá en algún momento) es posible que desee verificar el Composite Pattern. Esto es ideal para trabajar con "Estructuras similares a árboles" ..

Como dije, te conozco Sólo están esperando un sub-nivel, pero esto realmente podría ser útil para usted si más adelante necesita extender^_^

7

Creo que lo que es posible que después (como una aplicación literal de que se trate) es:

pubic class TokenTree 
{ 
    public TokenTree() 
    { 
     tree = new Dictionary<string, IDictionary<string,string>>(); 
    } 

    IDictionary<string, IDictionary<string, string>> tree; 
} 

En realidad, dijo una "lista" de pares clave-valor en su pregunta por lo que es posible que desee cambiar el IDictionary interno con un:

IList<KeyValuePair<string, string>> 
Cuestiones relacionadas