С# способ имитировать синтаксис словаря Python
Есть ли хороший способ в С# для имитации следующего синтаксиса python:
mydict = {}
mydict["bc"] = {}
mydict["bc"]["de"] = "123"; # <-- This line
mydict["te"] = "5"; # <-- While also allowing this line
Другими словами, мне бы хотелось что-то с доступом к [] стилю, который может вернуть либо другой словарь, либо тип строки, в зависимости от того, как он был установлен.
Я пытаюсь работать с обычным классом, но не может показаться успешным. Любые идеи?
Спасибо!
Править: я злюсь, я знаю. Решение Джареда Пар отлично., для двухуровневого словаря этой формы. Однако мне также интересны дальнейшие уровни., например,
mydict["bc"]["df"]["ic"] = "32";
И так далее. Любые идеи об этом?
Изменить 3:
Вот последний класс, в котором я закончил:
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;
}
Этот класс работает для бесконечных уровней и может быть прочитан без явного преобразования (опасно, может быть, но эй).
Использование так:
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";
Большое спасибо Джаред Пар!
Ответы
Ответ 1
Вы можете добиться этого, имея класс, назовем его PythonDictionary, который возвращается из mydict["bc"]
, имеют следующие члены.
- Свойство indexer для доступа к [ "de" ]
- Неявное преобразование из строки в PythonDictionary
Это должно позволить обоим случаям скомпилировать только штраф.
Например
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";
}
Ответ 2
Спасибо, что разместили этот вопрос и разрешение. Преобразован в 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
Использование:
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"