2009-02-20 18 views
55

¿Cómo crearía un diccionario de valores múltiples en C#?Diccionario de valores múltiples

E.g. Dictionary<T,T,T> donde la primera T es la clave y los otros dos son valores.

por lo que este sería posible: Dictionary<int,object,double>

Gracias

Respuesta

57

Basta con crear un tipo Pair<TFirst, TSecond> y usar eso como su valor.

Tengo un ejemplo de uno en mi C# in Depth source code. Reproducida aquí por simplicidad:

using System; 
using System.Collections.Generic; 

public sealed class Pair<TFirst, TSecond> 
    : IEquatable<Pair<TFirst, TSecond>> 
{ 
    private readonly TFirst first; 
    private readonly TSecond second; 

    public Pair(TFirst first, TSecond second) 
    { 
     this.first = first; 
     this.second = second; 
    } 

    public TFirst First 
    { 
     get { return first; } 
    } 

    public TSecond Second 
    { 
     get { return second; } 
    } 

    public bool Equals(Pair<TFirst, TSecond> other) 
    { 
     if (other == null) 
     { 
      return false; 
     } 
     return EqualityComparer<TFirst>.Default.Equals(this.First, other.First) && 
       EqualityComparer<TSecond>.Default.Equals(this.Second, other.Second); 
    } 

    public override bool Equals(object o) 
    { 
     return Equals(o as Pair<TFirst, TSecond>); 
    } 

    public override int GetHashCode() 
    { 
     return EqualityComparer<TFirst>.Default.GetHashCode(first) * 37 + 
       EqualityComparer<TSecond>.Default.GetHashCode(second); 
    } 
} 
+2

¿Cuál es la ventaja sobre un KeyValuePair normal? ¿Hay algún tipo de sobrecarga al usar un KeyValuePair? – tanascius

+1

Principalmente es una diferencia de énfasis, mientras que KeyValuePair en realidad encapsula un par de valores, implica un tipo particular de relación entre ellos ... esto no lo hace. –

+13

¿Es esto lo mismo que Tuple en .Net 4.0? – adam0101

3

no creo que pueda hacerlo directamente. Puede crear una clase que contenga tanto su object como double y poner una instancia del mismo en el diccionario.

class Pair 
{ 
    object obj; 
    double dbl; 
} 

Dictionary<int, Pair> = new Dictionary<int, Pair>(); 
19
Dictionary<T1, Tuple<T2, T3>> 

Edit: Lo siento - me olvidó que no te Tuplas hasta .NET 4.0 sale. D'oh!

+1

Las tuplas están en .NET 4.0 BCL, y no están relacionadas con C# 4.0. Las características de C# 4.0 no tienen mención sobre el soporte de tuplas. Por favor, corrige tu respuesta. –

+0

El problema con la tupla es que los valores no tienen nombre. – ProfK

+1

Además, los valores de Tuplo son de solo lectura, lo que podría estar bien para algunos casos, pero debe tenerse en cuenta antes de usarlos. –

2

Si los valores están relacionados, ¿por qué no los encapsula en una clase y simplemente utiliza el diccionario antiguo?

+0

Será más legible que Pair y Tuple también. ¿Qué es Primero, Segundo, Artículo1, Artículo2? – KornMuffin

5

Creo que esto es bastante exagerado para una semántica de diccionario, ya que el diccionario es por definición una colección de claves y sus respectivos valores, al igual que la forma en que vemos un libro del diccionario que contiene una palabra como clave y su significado descriptivo como el valor.

Sin embargo, puede representar un diccionario que puede contener colección de valores, por ejemplo:

Dictionary<String,List<Customer>> 

O un diccionario de una clave y el valor como un diccionario:

Dictionary<Customer,Dictionary<Order,OrderDetail>> 

Entonces' Tendré un diccionario que puede tener múltiples valores.

+0

¡Buena respuesta ...! – nawfal

+1

Tan pronto como empiece a anidar diccionarios, su código comenzará a verse como matrices multidimensionales. – IAbstract

+0

@IAbstract no es tan similar en semántica. Las matrices multidimensionales no se preocupan por la combinación de pares clave-valor. Además, las matrices multidimensionales no se preocupan por el elemento máximo de dos (al igual que el diccionario debe tener). –

1

Describe un multimapa.

Puede hacer que el valor sea un objeto List, para almacenar más de un valor (> 2 para la extensibilidad).

Reemplazar el objeto del diccionario.

41

Si está intentando agrupar valores, esta puede ser una gran oportunidad para crear una estructura o clase simple y usar eso como el valor en un diccionario.

public struct MyValue 
{ 
    public object Value1; 
    public double Value2; 
} 

entonces usted podría tener su diccionario

var dict = new Dictionary<int, MyValue>(); 

incluso se podría ir un paso más allá y poner en práctica su propia clase de diccionario que se encargará de las operaciones especiales que puedas necesitar.por ejemplo, si quería tener un método Add que acepta un int, objeto, y el doble

public class MyDictionary : Dictionary<int, MyValue> 
{ 
    public void Add(int key, object value1, double value2) 
    { 
     MyValue val; 
     val.Value1 = value1; 
     val.Value2 = value2; 
     this.Add(key, val); 
    } 
} 

entonces simplemente podría crear instancias y añadir al diccionario como tal y no tiene que preocuparse acerca de la creación 'MyValue 'estructuras:

var dict = new MyDictionary(); 
dict.Add(1, new Object(), 2.22); 
1

que resuelven usando:

Dictionary<short, string[]> 

gusta esta

Dictionary<short, string[]> result = new Dictionary<short, string[]>(); 
result.Add(1, 
      new string[] 
        { 
        "FirstString", 
        "Second" 
        } 
       ); 
     } 
return result; 
Cuestiones relacionadas