2008-08-12 25 views
69

Vì vậy, tôi đã được poking xung quanh với C# một chút thời gian gần đây, và tất cả các bộ sưu tập chung có tôi một chút bối rối. Nói rằng tôi muốn đại diện cho một cấu trúc dữ liệu nơi đầu của một cây là một cặp giá trị khóa, và sau đó có một danh sách tùy chọn các cặp giá trị khóa bên dưới (nhưng không có nhiều cấp độ hơn các giá trị này). Điều này có phù hợp không?Triển khai tốt nhất cho cấu trúc dữ liệu cặp giá trị khóa?

public class TokenTree 
{ 
    public TokenTree() 
    { 
     /* I must admit to not fully understanding this, 
     * I got it from msdn. As far as I can tell, IDictionary is an 
     * interface, and Dictionary is the default implementation of 
     * that interface, right? 
     */ 
     SubPairs = new Dictionary<string, string>(); 
    } 

    public string Key; 
    public string Value; 
    public IDictionary<string, string> SubPairs; 
} 

Nó chỉ thực sự là một shunt đơn giản để truyền dữ liệu.

Trả lời

132

Có một Data Type thực tế gọi là KeyValuePair, sử dụng như thế này

KeyValuePair<string, string> myKeyValuePair = new KeyValuePair<string,string>("defaultkey", "defaultvalue"); 
+1

Điều này làm việc tuyệt vời với tuyên bố "sử dụng" (tương tự như typedef cũ) để tiết kiệm một số cách gõ và làm cho mọi thứ rõ ràng hơn. Nếu bạn liên tục sử dụng e. g. cặp (chuỗi, chuỗi). –

+8

KeyValuePair NAME_HERE = new KeyValuePair ("defaultkey", "defaultvalue"); – HasanAboShally

+1

Để mở rộng nhận xét của @AndreasReiff: 'using NameValuePair = System.Collections.Generic.KeyValuePair ;' gần đầu mỗi tệp cần cấu trúc '(string, string)'. Mặc dù tôi thấy thuận tiện hơn khi tạo một 'class NameValuePair' trong không gian tên của tôi:' public class NameValuePair \t { \t \t KeyValuePair it; \t \t công NameValuePair (string name, chuỗi giá trị) \t \t { \t \t \t nó = new KeyValuePair (tên, giá trị); \t \t} \t \t chuỗi công khai Tên {get {return it.Key; }} \t \t chuỗi công khai Giá trị {get {return it.Value; }} \t} ' – ToolmakerSteve

1

Dictionary Class là chính xác những gì bạn muốn, chính xác.

Bạn có thể khai báo trực tiếp trường dưới dạng Từ điển, thay vì IDictionary, nhưng tùy thuộc vào bạn.

5

Có loại KeyValuePair tích hợp sẵn. Như một vấn đề của thực tế, đây là những gì IDictionary là cung cấp cho bạn truy cập vào khi bạn lặp lại trong nó.

Ngoài ra, cấu trúc này hầu như không phải là cây, việc tìm một tên đại diện hơn có thể là một bài tập tốt.

12

Một điều có thể bạn có thể làm là sử dụng đối tượng từ điển thẳng ra khỏi hộp và sau đó chỉ cần mở rộng nó với những thay đổi của riêng bạn:

public class TokenTree : Dictionary<string, string> 
{ 
    public IDictionary<string, string> SubPairs; 
} 

này mang lại cho bạn những lợi thế của việc không phải thực thi các quy tắc của IDictionary cho Khóa của bạn (ví dụ, tính duy nhất của khóa, v.v.).

Và yup bạn có khái niệm về các nhà xây dựng đúng :)

2

@Jay Mooney: Một điển lớp generic trong .NET thực sự là một bảng băm, chỉ với các loại cố định.

Mã bạn đã hiển thị không được thuyết phục bất kỳ ai sử dụng Hashtable thay vì từ điển, vì cả hai phần mã đều có thể được sử dụng cho cả hai loại.

Đối Hashtable:

foreach(object key in h.keys) 
{ 
    string keyAsString = key.ToString(); // btw, this is unnecessary 
    string valAsString = h[key].ToString(); 

    System.Diagnostics.Debug.WriteLine(keyAsString + " " + valAsString); 
} 

Đối với từ điển:

foreach(string key in d.keys) 
{ 
    string valAsString = d[key].ToString(); 

    System.Diagnostics.Debug.WriteLine(key + " " + valAsString); 
} 

Và cũng giống như nhau đối với một trong những khác với KeyValuePair, chỉ cần sử dụng các phiên bản không phải chung cho Hashtable, và phiên bản chung cho Từ điển. Vì vậy, nó cũng dễ dàng theo cả hai cách, nhưng Hashtable sử dụng Object cho cả khóa và giá trị, có nghĩa là bạn sẽ đóng tất cả các loại giá trị, và bạn không có an toàn kiểu, và từ điển sử dụng các kiểu generic và do đó tốt hơn.

1

Sử dụng một cái gì đó như thế này:

class Tree <T> : Dictionary < T, IList< Tree <T> > > 
{ 
} 

Nó xấu xí, nhưng tôi nghĩ rằng nó sẽ cung cấp cho bạn những gì bạn muốn. KeyValuePair quá tệ bị niêm phong.

3

Chỉ một điều để thêm vào điều này (mặc dù tôi nghĩ bạn đã có câu hỏi của bạn được trả lời bởi người khác).Vì lợi ích của khả năng mở rộng (vì chúng ta đều biết nó sẽ xảy ra tại một số điểm), bạn có thể muốn xem Composite Pattern Điều này lý tưởng để làm việc với "Cấu trúc giống cây" ..

Như tôi đã nói, tôi biết bạn chỉ mong đợi một phụ cấp, nhưng điều này thực sự có thể hữu ích cho bạn nếu sau này bạn cần phải mở rộng^_^

7

tôi nghĩ rằng những gì bạn có thể sau (như một thực hiện nghĩa đen của bạn hỏi) là:

pubic class TokenTree 
{ 
    public TokenTree() 
    { 
     tree = new Dictionary<string, IDictionary<string,string>>(); 
    } 

    IDictionary<string, IDictionary<string, string>> tree; 
} 

Bạn đã thực sự nói "danh sách" khóa-giá trị trong câu hỏi của bạn để bạn có thể muốn trao đổi IDictionary bên trong bằng:

IList<KeyValuePair<string, string>> 
Các vấn đề liên quan