【问题标题】:C# way to mimic Python Dictionary Syntax模仿 Python 字典语法的 C# 方法
【发布时间】:2010-11-25 18:22:19
【问题描述】:

在 C# 中是否有模仿以下 python 语法的好方法:

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

换句话说,我想要一些具有 [] 样式访问权限的东西,它可以返回另一个字典或字符串类型,具体取决于它的设置方式。

我一直在尝试使用自定义类解决此问题,但似乎无法成功。有什么想法吗?

谢谢!

编辑:我很邪恶,我知道。 Jared Par 的解决方案很棒。 . .对于这种形式的 2 级字典。但是,我也对进一步的级别感到好奇。 . .例如,

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";

非常感谢 Jared Par!

【问题讨论】:

    标签: c# python syntax dictionary types


    【解决方案1】:

    您可以通过类来实现这一点,我们称之为 PythonDictionary,它从mydict["bc"] 返回,具有以下成员。

    • 允许 ["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";
    }
    

    【讨论】:

    • 做得很好。我讨厌这些隐式转换,但它确实可以让你做 OP 想要的。
    • 1 或 2 键的绝佳解决方案。 . .我喜欢它,它可能适用于我的情况(非常感谢!)。但是,我也对更深层次的词典感到好奇。有什么想法吗?
    • 是的,它非常可扩展。结果类显示有问题。非常感谢!
    【解决方案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"
    

    【讨论】:

    • 这个答案不太符合Stack Overflow 的政策(并被标记为这样),因为它没有回答 OP 的问题(关于 C#。)但我认为它增加了价值.我建议不要删除它。但是请注意,寻找纯 VB 解决方案的人可能不会考虑检查这个问题。
    • 只是想贡献一下。
    • @jmjhonson85 我尊重这一点。我在审核队列中阅读了您的答案,因为它已被标记。可以这么说,我只是希望给你介绍一下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-20
    • 1970-01-01
    • 2011-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多