2009-09-04 9 views
12

Y at-il une bonne façon en C# pour imiter la syntaxe python suivant:C# façon à imiter Python Dictionnaire Syntaxe

mydict = {} 
mydict["bc"] = {} 
mydict["bc"]["de"] = "123"; # <-- This line 
mydict["te"] = "5";   # <-- While also allowing this line 

En d'autres termes, je voudrais quelque chose avec un accès de style [] qui peut renvoyer soit un autre dictionnaire ou un type de chaîne, selon la façon dont il a été défini.

J'ai essayé de travailler avec une classe personnalisée, mais je n'arrive pas à réussir. Des idées?

Merci!

Edit: Je suis méchant, je sais. La solution de Jared Par est géniale. . . pour un dictionnaire à deux niveaux de ce formulaire. Cependant, je suis également curieux de connaître d'autres niveaux. . . par exemple,

mydict["bc"]["df"]["ic"] = "32"; 

Et ainsi de suite. Des idées à ce sujet?

Edit 3:

Voici la dernière classe, je fini par utiliser:

class PythonDict { 
    /* Public properties and conversions */ 
    public PythonDict this[String index] { 
     get { 
      return this.dict_[index]; 
     } 
     set { 
      this.dict_[index] = value; 
     } 
    } 

    public static implicit operator PythonDict(String value) { 
     return new PythonDict(value); 
    } 

    public static implicit operator String(PythonDict value) { 
     return value.str_; 
    } 

    /* Public methods */ 
    public PythonDict() { 
     this.dict_ = new Dictionary<String, PythonDict>(); 
    } 

    public PythonDict(String value) { 
     this.str_ = value; 
    } 

    public bool isString() { 
     return (this.str_ != null); 
    } 

    /* Private fields */ 
    Dictionary<String, PythonDict> dict_ = null; 
    String str_ = null; 
} 

Cette classe fonctionne pour des niveaux infinis, et peut être lu à partir sans conversion explicite (dangereux, peut-être, mais bon).

Utilisation comme ceci:

 PythonDict s = new PythonDict(); 
     s["Hello"] = new PythonDict(); 
     s["Hello"]["32"] = "hey there"; 
     s["Hello"]["34"] = new PythonDict(); 
     s["Hello"]["34"]["Section"] = "Your face"; 
     String result = s["Hello"]["34"]["Section"]; 
     s["Hi there"] = "hey"; 

Merci beaucoup Jared Par!

Répondre

12

Vous pouvez obtenir ceci en ayant la classe, appelons-le PythonDictionary, qui est retourné de mydict["bc"] avoir les membres suivants.

  • Une propriété indexeur pour permettre la [ « de »] accès
  • Une conversion implicite de chaîne à PythonDictionary

Cela devrait permettre aux deux cas de compiler très bien.

Par exemple

public class PythonDictionary { 
    public string this[string index] { 
     get { ... } 
     set { ... } 
    } 
    public static implicit operator PythonDictionary(string value) { 
     ... 
    } 
} 

public void Example() { 
    Dictionary<string, PythonDictionary> map = new Dictionary<string, PythonDictionary>(); 
    map["42"]["de"] = "foo"; 
    map["42"] = "bar"; 
} 
+0

Très bien fait. Je déteste ces conversions implicites, mais cela vous permet certainement de faire ce que l'OP veut. –

+1

Excellente solution pour 1 ou 2 clés. . . J'aime ça pour ça, et ça marcherait probablement dans mon cas (donc merci beaucoup!). Cependant, je suis également curieux au sujet des dictionnaires plus profonds. Des idées là-bas? –

+0

Ouais, c'était très extensible. La classe résultante est montrée en question. Merci beaucoup! –

1

Merci pour l'affichage de cette question et de la résolution. Converti en VB.NET:

Public Class PythonDict 
    ' Public properties and conversions 
    Default Public Property Item(ByVal index As String) As PythonDict 
     Get 
      Return Me.dict_(index) 
     End Get 

     Set(value As PythonDict) 
      Me.dict_(index) = value 
     End Set 
    End Property 

    Public Shared Narrowing Operator CType(value As String) As PythonDict 
     Return New PythonDict(value) 
    End Operator 

    Public Shared Widening Operator CType(value As PythonDict) As String 
     Return value.str_ 
    End Operator 

    ' Public methods 
    Public Sub New() 
     Me.dict_ = New Dictionary(Of String, PythonDict)() 
    End Sub 

    Public Sub New(value As String) 
     Me.str_ = value 
    End Sub 

    Public Function isString() As Boolean 
     Return (Me.str_ IsNot Nothing) 
    End Function 

    ' Private fields 
    Private dict_ As Dictionary(Of String, PythonDict) = Nothing 
    Private str_ As String = Nothing 
End Class 

Utilisation:

Dim s As PythonDict = New PythonDict() 
s("Hello") = New PythonDict() 
s("Hello")("32") = "hey there" 
s("Hello")("34") = New PythonDict() 
s("Hello")("34")("Section") = "Your face" 
Dim result As String = s("Hello")("34")("Section") 
s("Hi there") = "hey" 
+0

Cette réponse ne correspond pas vraiment à la politique de [so] (et a été signalée comme telle), car elle ne répond pas à la question de l'OP (à propos de C#.) Mais je pense qu'elle ajoute de la valeur. Je le recommande * pas * être supprimé. Notez, cependant, que quelqu'un qui cherche une solution VB seulement ne pense pas à vérifier cette question. – jpaugh

+1

J'essaie juste de contribuer. – jmjohnson85

+0

@ jmjhonson85 Je respecte cela. J'ai lu votre réponse dans une file d'attente de révision, car elle était marquée. J'espère juste vous donner la configuration de la terre, pour ainsi dire. – jpaugh