StringDictionary so với Từ điển <chuỗi, chuỗi>


76

Có ai biết sự khác biệt thực tế giữa đối tượng System.Collections.Specialized.StringDictionary và System.Collections.Generic.Dictionary là gì không?

Tôi đã sử dụng cả hai trong quá khứ mà không cần suy nghĩ nhiều về việc cái nào sẽ hoạt động tốt hơn, hoạt động tốt hơn với Linq hoặc cung cấp bất kỳ lợi ích nào khác.

Bất kỳ suy nghĩ hoặc đề xuất nào về lý do tại sao tôi nên sử dụng cái này thay cho cái kia?

Câu trả lời:


90

Dictionary<string, string>là một cách tiếp cận hiện đại hơn. Nó thực hiện IEnumerable<T>và nó phù hợp hơn với những thứ LINQy.

StringDictionarylà lối học cũ. Nó đã có trước ngày thuốc chung. Tôi sẽ chỉ sử dụng nó khi giao tiếp với mã kế thừa.


Bạn nên chuẩn để xem cái nào hoạt động tốt hơn cho tình huống đặc biệt của bạn. Tôi không mong đợi một sự khác biệt hiệu suất đáng chú ý. Tôi khuyên bạn nên sử dụng Dictionary<string,string>cho tất cả mã mới (trừ khi bạn cần nhắm mục tiêu 1.1).
mmx

2
@thecoop không có dữ liệu khó để trình bày từ phía tôi bây giờ, nhưng một lần khi tôi kiểm tra tốc độ StringDictionaryhoạt động kém hơn (mặc dù tất cả những điều đó chủ yếu không quan trọng). Thành thật mà nói, trước đó tôi đã có khái niệm rằng StringDictionarymột bộ sưu tập chuyên biệt nào đó dành cho việc tăng tốc mọi thứ khi nào stringlà chìa khóa và tôi rất ngạc nhiên khi nó hoạt động kém hơn trong thử nghiệm của tôi, tôi đã tìm kiếm nó chỉ để biết rằng nó không phải là không cần thiết
nawfal

1
@nawfal Tôi nghĩ nó chậm hơn vì StringDictionary theo mặc định không phân biệt chữ hoa chữ thường. Nếu bạn tạo một từ điển với case-insensitive chính Comparer sau đó tôi tin rằng hiệu suất sẽ giống nhau
phuclv

41

Điểm khác.

Điều này trả về null:

StringDictionary dic = new StringDictionary();
return dic["Hey"];

Điều này ném ra một ngoại lệ:

Dictionary<string, string> dic = new Dictionary<string, string>();
return dic["Hey"];

Các "ném một ngoại lệ" tính năng của Dictionary<>phương tiện tôi không bao giờ có thể sử dụng []. Sử dụng StringDictionary đã xóa nhiều mã của tôi.
James Curran

1
@James Tôi hơi muộn nhưng có lẽ bạn nên sử dụng TryGetValue.
Şafak Gür

@ ŞafakGür - Tôi làm sử dụng TryGetValue () - bởi vì tôi không bao giờ có thể sử dụng [ ]vì nó ném một ngoại lệ. (StringDictionary chỉ giải quyết này cho một loại từ điển)
James Curran

@James, tôi tin rằng việc ném một ngoại lệ cho các khóa không tồn tại là một lựa chọn API tốt hơn vì null được cho phép làm giá trị từ điển. Bằng cách này, bạn có thể phân biệt giữa khóa không tồn tại với khóa có giá trị là null.
Şafak Gür

1
@ ŞafakGür điều này đúng - nếu nhu cầu của bạn là một từ điển mà a) luôn phải có tất cả các giá trị, b) có thể chứa các giá trị rỗng và c) các giá trị này có nghĩa khác với "không có giá trị" .. Tuy nhiên, trong từ điển "không giá trị "thường được đại diện bởi khóa không có ở đó. Tuy nhiên, lý do thực sự mà Dictionary <> ném ra một ngoại lệ là vì giá trị có thể là một kiểu giá trị (và do đó, không thể được biểu diễn bằng giá trị rỗng).
James Curran

37

Như Reed Copsey đã chỉ ra, StringDictionary viết thường các giá trị khóa của bạn. Đối với tôi, điều này hoàn toàn bất ngờ, và là một chương trình biểu diễn.

private void testStringDictionary()
{
    try
    {
        StringDictionary sd = new StringDictionary();
        sd.Add("Bob", "My name is Bob");
        sd.Add("joe", "My name is joe");
        sd.Add("bob", "My name is bob"); // << throws an exception because
                                         //    "bob" is already a key!
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Tôi thêm câu trả lời này để thu hút sự chú ý nhiều hơn đến sự khác biệt to lớn này , IMO quan trọng hơn sự khác biệt hiện đại và cổ điển.


4
Nếu vì lý do nào đó người ta muốn cùng một hành vi với Từ điển <chuỗi, chuỗi> thì có thể sử dụng: Từ điển <chuỗi, chuỗi> ht = new Từ điển <chuỗi, chuỗi> (StringComparer.OrdinalIgnoreCase); ht.Add ("Bob", "ff"); ht.Add ("bob", "ff"); // ném ngoại lệ
osexpert

36

Tôi nghĩ rằng StringDictionary đã lỗi thời khá nhiều. Nó tồn tại trong phiên bản.1 của framework (trước generic), vì vậy nó là một phiên bản cao cấp hơn vào thời điểm đó (so với từ điển không phải generic), nhưng tại thời điểm này, tôi không tin rằng có bất kỳ lợi thế cụ thể nào với nó. trên từ điển.

Tuy nhiên, có những nhược điểm đối với StringDictionary. StringDictionary tự động viết thường các giá trị khóa của bạn và không có tùy chọn nào để kiểm soát điều này.

Xem:

http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/59f38f98-6e53-431c-a6df-b2502c60e1e9/


2
StringDictionarycó thể được sử dụng trong Properites.Settingskhi Dictionary<string,string>không thể. Vì vậy, lỗi thời hay không, vẫn còn một số sử dụng cho StringDictionary.
jahu

2

StringDictionary đến từ .NET 1.1 và thực hiện IEnumerable

Dictionary<string, string> đến từ .NET 2.0 và triển khai IDictionary<TKey, TValue>,IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable

Bỏ quaCase chỉ được đặt cho Key in StringDictionary

Dictionary<string, string> tốt cho LINQ

        Dictionary<string, string> dictionary = new Dictionary<string, string>();
        dictionary.Add("ITEM-1", "VALUE-1");
        var item1 = dictionary["item-1"];       // throws KeyNotFoundException
        var itemEmpty = dictionary["item-9"];   // throws KeyNotFoundException

        StringDictionary stringDictionary = new StringDictionary();
        stringDictionary.Add("ITEM-1", "VALUE-1");
        var item1String = stringDictionary["item-1"];     //return "VALUE-1"
        var itemEmptystring = stringDictionary["item-9"]; //return null

        bool isKey = stringDictionary.ContainsValue("VALUE-1"); //return true
        bool isValue = stringDictionary.ContainsValue("value-1"); //return false

1

Bên cạnh việc là một lớp "hiện đại" hơn, tôi nhận thấy rằng Dictionary có hiệu quả về bộ nhớ hơn StringDictionary bởi một biên độ lớn.


11
chúng tôi có thể sử dụng một số con số ở đây
Zonko

1

Một điểm liên quan khác là (sửa cho tôi nếu tôi sai ở đây) System.Collections.Generic.Dictionarykhông thể được sử dụng trong cài đặt ứng dụng ( Properties.Settings) trong khi đó System.Collections.Specialized.StringDictionary.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.