2010-11-05 15 views
26

J'ai besoin d'un moyen de stocker des paires clé/valeur où la valeur peut être de différents types.Comment créer un dictionnaire contenant différents types dans C#

J'aime faire:

int i = 12; 
string s = "test"; 
double x = 24.1; 

Storage.Add("age", i); 
Storage.Add("name", s); 
Storage.Add("bmi", x); 

Et plus tard, récupérer les valeurs avec:

int a = Storage.Get("age"); 
string b = Storage.Get("name"); 
double c = Storage.Get("bmi"); 

Comment un stockage comme ça ressemble? Merci, Erik

Répondre

48

Eh bien, vous pouvez utiliser Dictionary<string, dynamic> en C# 4/.NET 4 - mais à part ça, vous ne pouvez pas le faire avec exactement le code affiché parce qu'il n'y a pas de type qui est implicitement convertible en int, string et double. (Vous pouvez écrire votre propre, mais vous auriez à la liste chaque type séparément.)

Vous pouvez utiliser Dictionary<string, object> mais vous auriez besoin de jeter les résultats:

int a = (int) Storage.Get("age"); 
string b = (string) Storage.Get("name"); 
double c = (double) Storage.Get("bmi"); 

Sinon, vous pourriez rendre la méthode générique Get:

int a = Storage.Get<int>("age"); 
// etc 
+0

Peut-être que quelqu'un devrait créer un type de variante? AIDE, je suis aveugle! –

+2

Je suis d'accord avec Jon Skeet. Encore. Mais faire quelque chose comme ça signifie que vous faites quelque chose de mal. Vous devez d'abord réfléchir aux raisons pour lesquelles vous devez stocker différentes valeurs dans un seul dictionnaire. – Euphoric

+0

Merci beaucoup, la méthode générique Get était la chose que je cherchais !! – Enrico

6

Pourquoi ne pas utiliser:

Dictionary<string, object> 

Vous pouvez créer une méthode d'extension pour les jeter quand vous les obtenez:

public static class DictionaryExcetions 
{ 
    public static T Get<T>(this Dictionary<string, object> instance, string name) 
    { 
     return (T)instance[name]; 
    } 

} 

var age = dictionary.Get<int>("age"); 
2
Dictionary<string, object> 
1

Vous pouvez utiliser un Dictionary<string,object> et vous pouvez mettre tout ce que vous voulez dedans. Vous auriez à jeter les résultats au bon type quand vous les sortez bien.

En regardant votre exemple, vous pourriez vouloir considérer si une classe simple pour stocker les données pourrait être plus ce que vous voulez et permettre une meilleure sécurité de type. Cela dépend si vous avez un ensemble limité de choses à mettre dans la classe ou si vous avez besoin du stockage potentiellement illimité/inconnu d'un dictionnaire.

0

Le dictionnaire est clairement la solution la plus rapide.

Une autre façon pourrait être de stocker une classe personnalisée dans laquelle vous pouvez stocker la valeur réelle et les informations concernant son type

19

Vous pourrait déclarer un dictionnaire contenant juste le type object puis jeter vos résultats; .par exemple.

Dictionary<string, object> storage = new Dictionary<string,object>(); 

storage.Add("age", 12); 
storage.Add("name", "test"); 
storage.Add("bmi", 24.1); 

int a = (int)storage["age"]; 
string b = (string)storage["name"]; 
double c = (double)storage["bmi"]; 

Cependant, ce n'est pas si élégant. Si vous savez que vous allez toujours stocker l'âge, le nom, bmi je créerais un objet pour encapsuler ceux-ci et stocker cela à la place. Par exemple.

public class PersonInfo 
{ 
    public int Age { get; set; } 
    public string Name { get; set; } 
    public double Bmi { get; set; } 
} 

Ensuite, utilisez l'insead du dictionnaire ... par ex.

PersonInfo person1 = new PersonInfo { Name = "test", Age = 32, Bmi = 25.01 }; 

int age = person1.Age; 

etc.

2

Étant donné que vous ne voulez pas une collection de données fortement typée, j'aurais pensé qu'un HashTable conviendrait à votre situation. Vous pouvez également créer une méthode d'extension pour cela, comme une autre affiche suggérée pour l'implémentation du dictionnaire.

E.g.

public static class StorageExtentions 
{ 
    public static T Get<T>(this Hashtable table, object key) 
    { 
     return (T) table[key]; 
    } 
} 

Votre code serait alors ressembler à:

int i = 12; 
string s = "test"; 
double x = 24.1; 
Hashtable Storage = new Hashtable(); 
Storage.Add("age", i); 
Storage.Add("name", s); 
Storage.Add("bmi", x); 
int a = Storage.Get<int>("age"); 
string b = Storage.Get<string>("name"); 
double c = Storage.Get<double>("bmi");