2010-10-20 8 views
6

Necesito organizar el tipo de diccionario donde la clave sería un par de enum y int y el valor es objeto. Entonces quiero asignar un par a algún objeto.¿Cómo usar la clave compuesta para el diccionario?

Una opción sería

public enum SomeEnum 
{ 
value1, value2 
} 

class Key 
{ 
    public SomeEnum; 
    public int counter; 

    // Do I have to implement Compare here? 
} 

Dictionary<SomeEnum, object> _myDictionary; 

Otra opción sería convertir la enumeración y int a alguna clave única.

string key = String.Format("{0}/{1}", enumValue, intValue) 

Ese enfoque requiere un análisis de cadenas, mucho trabajo extra.

¿Cómo hacerlo fácilmente?

+1

¿Qué versión de C# estás utilizando? –

+0

Visual Studio 2008, así que creo que es 3.5 –

+2

C# 3, .NET es 3.5 – Mike

Respuesta

9

Me gustaría ir con algo similar a

public enum SomeEnum 
{ 
value1, value2 
} 

public struct Key 
{ 
    public SomeEnum; 
    public int counter; 
} 

Dictionary<Key, object> 

creo que haría?

+0

Sí, eso es, de lejos, el más simple :) – leppie

+0

¿Cómo se compararían dos claves por diccionario? ¿Utiliza == o IComparable? –

+1

Es un tipo de valor, por lo que solo realizará un ==. No estoy seguro acerca de los sistemas de 32 bits, pero en un sistema de 64 bits creo que simplemente compararía dos ubicaciones de memoria, ya que la enumeración y la int encajarán en 64 bits, es una operación barata. En 32 bit, probablemente (?) Requeriría algunas instrucciones más? – Onkelborg

7

Si está utilizando C# 4.0, puede usar la clase Tuple.

var key = Tuple.Create(SomeEnum.Value1, 3); 
+1

Sí, pero luego no está bien tipeado, es decir, no hay una descripción de en qué consiste la clave. Pero sí, es posible – Onkelborg

+1

Está fuertemente tipado - la clave es del tipo 'Tuple '. –

+1

Para que su diccionario se pueda definir como 'Diccionario , object>' –

8

Si se va a poner esto en un diccionario, entonces usted tendrá que asegurarse de que se implementa una significativa .Equals y .GetHashCode o el diccionario no se comportará correctamente.

Comenzaré con algo como lo siguiente para la clave básica compuesta, y luego implementaré un IComparer personalizado para obtener el orden de clasificación que necesita.

public class MyKey 
{ 
    private readonly SomeEnum enumeration; 
    private readonly int number; 

    public MyKey(SomeEnum enumeration, int number) 
    { 
     this.enumeration = enumeration; 
     this.number = number; 
    } 

    public int Number 
    { 
     get { return number; } 
    } 

    public SomeEnum Enumeration 
    { 
     get { return enumeration; } 
    } 

    public override int GetHashCode() 
    { 
     int hash = 23 * 37 + this.enumeration.GetHashCode(); 
     hash = hash * 37 + this.number.GetHashCode(); 

     return hash; 
    } 

    public override bool Equals(object obj) 
    { 
     var supplied = obj as MyKey; 
     if (supplied == null) 
     { 
      return false; 
     } 

     if (supplied.enumeration != this.enumeration) 
     { 
      return false; 
     } 

     if (supplied.number != this.number) 
     { 
      return false; 
     } 

     return true; 
    } 
} 
+0

Oh .. tanto tipando ... ((( –

+2

+1 por mencionar los .Equals y GetHashCode gotcha. Esta es una buena razón para usar el tipo Tuple en lugar de rodar su propia clave simple. –

+0

@ Winston Smith: buen punto sobre Tuples –

Cuestiones relacionadas