Dictionnaire de listes génériques ou de types variés

Je veux un dictionnaire qui mappe les chaînes à des listes génériques de types variés. c’est-à-dire sous la forme suivante:

 Valeur clé
 Ssortingng List 
 Ssortingng List 
 Ssortingng List 
 Ssortingng List 
 ...

Actuellement, j’utilise un Dictionary , puis KeyValuePair pair liste fortement typée de chaque entrée de KeyValuePair pair dictionnaire KeyValuePair pair comme suit:

 Type layerType = pair.Value.GetType().GetGenericArguments()[0]; List objectsClicked = pair.Value as List; 

Y a-t-il une meilleure façon de faire cela?

[Edit] Comme il a été noté, ce qui précède ne comstack pas, excuses – c’est ce que vous obtenez lorsque vous posez une question pendant que vous travaillez encore sur quelque chose. Quelques explications supplémentaires. Je fais un visualiseur de données spatiales de base. La vue finale consiste en un groupe de Layer . Chaque couche fournit un délégué pour restituer son type (à partir d’un décalage et d’une échelle) et un moyen de vérifier quels objects se trouvent dans la fenêtre en cours. Pour les tests de toucher, je voudrais une liste pour chaque couche dont les objects ont été touchés. Cette liste serait une List pour un calque de Point , etc. Le regroupement des occurrences de tous les Layer serait alors un ensemble de listes fortement typées.

Que diriez-vous de Dictionary supposant que vous soyez sur C # 4

 Dictionary Dict = new Dictionary(); Dict.Add("int", new List()); Dict.Add("ssortingng", new List()); Dict["int"].Add(12); Dict["ssortingng"].Add("str"); foreach (KeyValuePair pair in Dict) { Type T = pair.Value.GetType(); Console.WriteLine(T.GetGenericArguments()[0].ToSsortingng()); } 

Qui imprime

System.Int32

System.Ssortingng

Est-ce ce que vous cherchez?

Utiliser Dictionary est probablement la seule solution. Mais votre code est faux, vous ne pouvez pas utiliser de génériques comme celui-là. Vous ne pouvez pas créer de type dynamicaly comme ceci.

Le problème général de votre besoin est qu’il n’est pas compatible avec un langage fort, tel que C #. En langage fortement typé, vous devez savoir quel type est EXACTEMENT. Mais cela ne peut être fait en utilisant des moyens normaux. De plus, votre compréhension des génériques est fausse. Sa seule extension de compilation au type.

Et idée générale : dans votre cas, utilisez une sorte de hiérarchie des blocs que vous enregistrez dans ces listes. Ce sera une idée bien meilleure et plus sûre et ne fera pas que tous ceux qui regardent votre code arrachent ses cheveux.

Je vais prendre un juste milieu entre Euphoric et Adam, vous devriez utiliser à la fois IList et dynamic . Voici ce que je pense être plus correct:

 var dict = new Dictionary(); dict.Add("u", new List()); dict.Add("v", new List()); // in case of members you know they exist on an IList dict["u"].Add(new U()); dict["v"].Add(new V()); // in case you know what you are going to get back, in which case you should cast var uProperty = (dict["u"][0] as U).UProperty var vProperty = (dict["v"][0] as V).VProperty // in case your're not sure of (dict[someKey] as dynamic)[someIndex].SomeMember...; 

Tout cela est beaucoup plus simple que de compter sur la reflection. L’idée de base est de déclarer le type de valeur du dictionnaire comme étant IList pour clarifier vos intentions dès le départ, tout en faisant appel à dynamic pour atténuer la monstruosité de reflection et raccourcir le code.

En fait, je pense que l’approche plus propre consiste à créer une enveloppe pour votre dictionnaire:

 public class GlobalStore { private readonly IDictionary _globalStore; public GlobalStore() { _globalStore = new ConcurrentDictionary(); } public IEnumerable GetFromCache() where T : class { return (IEnumerable) _globalStore[typeof(T)]; } public void SetCache(IEnumerable cache) where T : class { _globalStore[typeof(T)] = cache; } } 

Voici un test pour cela:

 [TestClass] public class GlobalStoreTest { [TestMethod] public void GlobalStore_Test() { //Arrange var globalStore = new GlobalStore(); globalStore.SetCache(new List { new ClientModel { ClientId = 1, ClientName = "Client1" }, new ClientModel { ClientId = 2, ClientName = "Client2" } }); //Act var clients = globalStore.GetFromCache(); //Assert Assert.AreEqual(2, clients.Count()); } }