2009-09-04 32 views
12

Có cách nào tốt bằng C# để bắt chước cú pháp python sau:C# cách để bắt chước Python điển Cú pháp

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

Nói cách khác, tôi muốn một cái gì đó với [] truy cập phong cách mà có thể trở lại một trong hai khác từ điển hoặc loại chuỗi, tùy thuộc vào cách nó được đặt.

Tôi đã cố gắng để làm việc này với một lớp tùy chỉnh nhưng dường như không thể thành công. Bất kỳ ý tưởng?

Cảm ơn!

Chỉnh sửa: Tôi xấu xa, tôi biết. Giải pháp của Jared Par thật tuyệt vời. . . cho từ điển 2 cấp của biểu mẫu này. Tuy nhiên, tôi cũng tò mò về các cấp độ tiếp theo. . . ví dụ:

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

Và cứ tiếp tục như vậy. Bất kỳ ý tưởng về điều đó?

Sửa 3:

Đây là lớp học cuối cùng tôi đã kết thúc bằng:

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

Lớp này làm việc cho cấp độ vô hạn, và có thể được đọc từ mà không cần chuyển đổi rõ ràng (nguy hiểm, có thể, nhưng hey).

Cách sử dụng như sau:

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

Thank you very much Jared Mệnh!

Trả lời

12

Bạn có thể đạt được điều này bằng cách có lớp, cho phép gọi nó là PythonDictionary, được trả về từ mydict["bc"] có các thành viên sau.

  • Một tài sản indexer để cho phép [ "de"] truy cập
  • Một chuyển đổi ngầm từ chuỗi PythonDictionary

Điều đó sẽ cho phép cả hai trường hợp để biên dịch tốt.

Ví dụ

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

Rất độc đáo được thực hiện. Tôi ghét những chuyển đổi tiềm ẩn này, nhưng nó chắc chắn cho phép bạn làm những gì mà OP muốn. –

+1

Giải pháp tuyệt vời cho 1 hoặc 2 phím. . . Tôi thích nó cho điều đó, và nó có thể sẽ làm việc trong trường hợp của tôi (vì vậy cảm ơn bạn rất nhiều!). Tuy nhiên, tôi cũng tò mò về các từ điển sâu hơn. Có ý tưởng nào không? –

+0

Yup, nó đã được mở rộng rất nhiều. Lớp kết quả được hiển thị trong câu hỏi. Cảm ơn nhiều! –

1

Cám ơn đăng câu hỏi này và giải quyết. Chuyển đổi sang 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 

Cách sử dụng:

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

Câu trả lời này không hoàn toàn phù hợp với chính sách của [do đó] (và bị gắn cờ như vậy), bởi vì nó không trả lời câu hỏi của OP (về C#.) Nhưng tôi nghĩ nó thêm giá trị. Tôi đang đề xuất nó * không * bị xóa. Tuy nhiên, lưu ý rằng ai đó đang tìm kiếm giải pháp chỉ VB có thể không nghĩ đến việc kiểm tra câu hỏi này. – jpaugh

+1

Chỉ cố gắng đóng góp. – jmjohnson85

+0

@ jmjhonson85 Tôi tôn trọng điều đó. Tôi đã đọc câu trả lời của bạn trong hàng đợi đánh giá vì nó đã bị gắn cờ. Tôi chỉ hy vọng sẽ cung cấp cho bạn vị trí của vùng đất, để nói chuyện. – jpaugh

Các vấn đề liên quan