Imbriquée collection de dictionnaires en .NET
L' .NET Dictionary<TKey, TValue>
objet permet l'affectation des clés/valeurs comme:
Dictionary<string, string> dict = new Dictionary<string, string>();
dict["1"] = "foo";
dict["2"] = "bar";
mais je ne peux pas utiliser un Dictionnaire comme:
Dictionary<string, string> dict = new Dictionary<string, string>();
dict["F1"]["F2"]["F3"] = "foo";
dict["2"]["X"] = "bar";
Est là une collection dans .NET qui me permet de nid []
, ou devrais-je créer mon propre?
Si je dois créer mon propre, comment pourrais-je faire cela?
EDIT:
Il serait également utile si je pouvais avoir des implémentations qui attendent les clés uniques, comme suit:
dict["F1"]["F2"]["F3"] = "foo";
dict["F1"]["F2"]["F3"] = "bar"; //result is "bar" because "foo" was overridden
et une mise en œuvre lorsqu'une clé peut être utilisée plus d'une fois
dict["F1"]["F2"]["F3"] = "foo";
dict["F1"]["F2"]["F3"] = "bar"; //result can be "foo" and "bar"
Est-ce possible?
EDIT (comme par Jon Skeet la question):
Je veux utiliser la structure comme (comme un exemple approximatif):
json["data"]["request"]["name"] = "username";
json["data"]["request"]["pass"] = "password";
décide de
{ data: { request: { name: "username", pass: "password" } } }
et aussi il y aurait un équivalent pour XML etc.
Avez-vous vraiment besoin d'un arbitraires (et variables) niveau d'imbrication? Peut-être qu'on pourrait décrire l'image plus grande -, il est susceptible d'être d'une façon plus propre de l'atteindre.
la raison d'être, je veux une structure qui me permet de modéliser des choses comme JSON / XML à l'aide d'un .Collecte NETTE. Voir mon dernier edit
Une raison quelconque vous ne voulez pas seulement pour utiliser une librairie JSON (par ex. JSON.NET) qui a déjà est une représentation appropriée?
Mon point est que si vous utilisez un JSON ou XML bibliothèque, vous ne pourriez pas besoin d'écrire un extra dictionnaire à tous les...
Pas d'excuses nécessaire, je vous assure.
la raison d'être, je veux une structure qui me permet de modéliser des choses comme JSON / XML à l'aide d'un .Collecte NETTE. Voir mon dernier edit
Une raison quelconque vous ne voulez pas seulement pour utiliser une librairie JSON (par ex. JSON.NET) qui a déjà est une représentation appropriée?
Mon point est que si vous utilisez un JSON ou XML bibliothèque, vous ne pourriez pas besoin d'écrire un extra dictionnaire à tous les...
Pas d'excuses nécessaire, je vous assure.
OriginalL'auteur series0ne | 2012-09-22
Vous devez vous connecter pour publier un commentaire.
Avoir une exigence pour la arbitrairement long de nidification, je suis venu avec la solution suivante, qui, autant que je peux voir, ne casse pas, selon mon test:
TEST:
OriginalL'auteur series0ne
Vous pouvez faire cela en utilisant le Dictionnaire standard, vous avez juste à déclarer la nidification:
OriginalL'auteur zeebonk
L'original
Dictionary
objet COM qui a été créé pour travailler avec vb6 répondrait à une tentative d'accès à un non-existant élément par la création d'un nouvel élément de typeDictionary
avec le nom correspondant. Cette approche permet à quelque chose pour être stocké àMyDict["Foo"]["Bar"]
sans avoir à d'abord créerMyDict["Foo"]
. Le problème avec cette approche est que si on souhaite ajouter"Foo"
àMyDict
lors de l'exécution d'une écritureMyDict["Foo"]["Bar"]
, on serait plutôt de ne pas créer un tel article si l'on tentait, par exemple évaluerMyDict["Foo"]["Bar"].ValueOrDefault(someDefaultValue)
.J'ai utilisé de telles collections, car ils peuvent être utiles pour la modélisation de certaines choses (conceptuellement, elles ressemblent beaucoup aux documents XML). Une approche possible est de déclarer que les dictionnaires qui ne contiennent rien, mais d'autres dictionnaires sont considérés comme sémantiquement comme des non-entités qui peut être retirée à toute occasion. Lorsque implicitement l'ajout d'un sous-groupe, définir un indicateur dans l'élément auquel il est ajouté, indiquant qu'il doit être vérifié pour les articles qui peuvent être supprimés (ou de conserver un compteur du nombre de ces éléments peuvent exister). Puis, avec une certaine fréquence raisonnable, de balayer à travers les dictionnaires et supprimer ces "morts" éléments.
Une approche alternative est d'avoir l'index à partir du dictionnaire de ne pas retourner un élément réel, mais au lieu de retourner un "éphémère indexeur" type, qui conserve une référence à l'objet parent et a des méthodes internes
GetNestedForReading
,SetNestedForReading
,GetValue
, etSetValue
, qui dos de la chaîne d'elle. Une déclarationFoo["Bar"]["Boz"] = "George";
va finir de le remplir efficacementFoo.SetNestedForReading("Bar").SetValue("Boz", "George");
toutz = Foo["Bar"]["Boz"];
effectueFoo.GetNestedForReading("Bar").GetValue("Boz");
. L'appel deSetNestedForReading
méthode avec un inexistante clé permettra de créer et de renvoyer un nouvel élément imbriqué; laGetNestedForReading
méthode immuable "vide" de l'élément. En utilisant cette approche permettra ainsi d'éviter de créer des éléments vides.Bien que cette dernière approche est plus compliqué que l'ancien, il a un autre avantage. Il est possible d'avoir chaque nœud individuellement tenir sa collection d'une salle de profondément immuable dictionnaire ou un partage de mutables; si l'un
GetNestedForWriting
appel voit que l'objet imbriqué est immuable, il est possible de construire une nouvelle plate-mutable objet possédant les mêmes éléments. Si on définit la méthode de clonage pour une mutable nœud de la création d'un nouveau immuable nœud (immuable) des clones de tous les sous-nœuds, et la méthode de clonage de immuable nœud que le retour lui-même, le clonage des arbres qui sont pour la plupart immuable devient très bon marché. Si on avait un nouveau-cloné (donc immuable) à quatre niveaux de l'arbre avec seize points à chaque niveau (de 65 536 nœuds feuilles au total) et de tous les nœuds ont été partagés immuable, la mise à jour d'un nœud feuille n'aurait besoin que de remplacer une feuille et quatre autres nœuds avec mutable ceux. Le clonage de l'arbre n'aurait besoin que de créer de nouveaux objets immuables pour les nœuds qui ont été remplacés par mutable (p. ex. copie de cinq choses). Même si on peut avoir la commodité d'une mutable arbre, on aurait les avantages d'efficacité de l'immuable.Le plus gros "problème" que je vois avec cette approche est que pour éviter certains comportements bizarres il faut exiger l'utilisation de la syntaxe comme
MyDict["Foo"]["Bar"].Value = "George"
. Si la conversion implicite opérateurs ont été utilisés pour échapper à cette obligation, quelqu'un pourrait s'attendre à une déclaration commevar st = MyThing["Foo"]["Bar"];
de définirst
comme unstring
instantané de ce queMyThing["Foo"]["Bar"]
détient, à ce moment-là; au contraire, elle le définir comme quelque chose qui va de l'indice deMyThing["Foo"]["Bar"]
. Si l'on devait utiliser.Value
de lire ou d'écrire des chaînes de ce type, du fait que la variable n'était pas une chaîne apparente. Si on a utilisé implicite opérateurs pour permettre à ce type de missions, le comportement serait bizarre. C'est dommage qu'il n'y aucun moyen d'une fonction peut spécifier "ne permettent pas de valeur de retour pour être utilisé pour l'inférence de type".D'ailleurs, il est possible d'avoir l'indexeur le type d'une classe ou d'un générique struct. Si c'est une classe, un accès à
foo["Bar"]["boz"]["baz"]...
imbriquéeN
profonde nécessiterait la création deN
temporaire tas d'objets. Si c'est un générique de struct, elle entraînera la création deN
les structures, mais le plus profondément imbriquées les structures permettrait d'obtenir un plus grand. Pour des niveaux raisonnables de nidification, générique structs serait probablement un peu plus efficace, mais les classes serait probablement plus facile de travailler avec.OriginalL'auteur supercat
Vous décidez que ce soit pour soutenir un nombre fixe de la chaîne de clés à rechercher, ou de fournir un cadre plus général de mécanisme de clé si le nombre de touches peut varier. Pour le premier cas, essayez les solutions suivantes:
Pour le second cas, vous pouvez effectuer les opérations suivantes:
où la classe MyEqualityComparer serait quelque chose comme:
OriginalL'auteur John Källén
Utiliser un
Dictionary
commeTValue
:par exemple:
OriginalL'auteur Ria
Je pense, votre cas est le bon endroit pour utiliser
DynamicObject
. Je vais créer un exemple de json à l'aide deDictionary<string, object>
en interne.Même idée peut être utilisée pour xml aussi.
--
OriginalL'auteur L.B