Tại sao từ điển được ưa thích hơn Hashtable trong C #?


1396

Trong hầu hết các ngôn ngữ lập trình, từ điển được ưa thích hơn hashtables. Những lý do đằng sau đó là gì?


21
> Điều này không nhất thiết là đúng. Một bảng băm là một thực hiện của một từ điển. Một cái điển hình ở đó, và nó có thể là cái mặc định trong .NET, nhưng nó không phải là định nghĩa duy nhất. Tôi không chắc chắn rằng điều này được yêu cầu bởi tiêu chuẩn ECMA, nhưng tài liệu MSDN gọi rất rõ ràng là nó được triển khai dưới dạng hashtable. Họ thậm chí còn cung cấp lớp SortedList cho những lần thay thế hợp lý hơn.
Hứa hẹn

15
@Promit Tôi luôn nghĩ rằng đó Dictionarylà một triển khai Hashtable.
b1nary.atr0phy

2
Tôi nghĩ lý do là, trong một từ điển bạn có thể xác định loại khóa và giá trị cho selfe của bạn. Hashtable chỉ có thể lấy các đối tượng và lưu các cặp dựa trên hàm băm (từ object.GetHashCode ()).
Bộ tản nhiệt

2
@Dan Yêu cầu của bạn khá sai lầm ... một bảng băm chỉ chứa một phiên bản của mỗi khóa và một tìm kiếm không bao giờ mang lại nhiều mục; nếu bạn muốn liên kết nhiều giá trị với mỗi khóa, hãy đặt giá trị bảng băm thành một danh sách các giá trị. Không có cấu trúc dữ liệu như "Từ điển" ... Từ điển chỉ đơn giản là tên mà một số thư viện sử dụng cho bảng băm của họ. ví dụ: bảng băm không chung của C # được gọi HashTable. Khi họ thêm thuốc generic vào ngôn ngữ, họ gọi phiên bản chung Dictionary. Cả hai đều là bảng băm.
Jim Balter

3
@Dan Yêu cầu của bạn bị nhầm ... bảng băm ( en.wikipedia.org/wiki/Hash_table ) là một cách thực hiện cụ thể của một từ điển, còn gọi là một mảng kết hợp ( en.wikipedia.org/wiki/Associative_array ), và, một từ điển, chỉ chứa một phiên bản của mỗi khóa và một tìm kiếm không bao giờ mang lại nhiều mục; nếu bạn muốn liên kết nhiều giá trị với mỗi khóa, hãy đặt giá trị bảng băm thành một danh sách các giá trị. Và các lớp .NET Dictionary và Hashtable đều là bảng băm.
Jim Balter

Câu trả lời:


1568

Đối với những gì nó có giá trị, một từ điển (theo lý thuyết) một bảng băm.

Nếu bạn có nghĩa là "tại sao chúng ta sử dụng Dictionary<TKey, TValue>lớp thay vì Hashtablelớp?", Thì đó là một câu trả lời dễ dàng: Dictionary<TKey, TValue>là một loại chung chung, Hashtablekhông phải vậy. Điều đó có nghĩa là bạn có được sự an toàn kiểu Dictionary<TKey, TValue>, bởi vì bạn không thể chèn bất kỳ đối tượng ngẫu nhiên nào vào đó và bạn không phải bỏ các giá trị bạn đưa ra.

Thật thú vị, việc Dictionary<TKey, TValue>triển khai trong .NET Framework dựa trên Hashtable, như bạn có thể biết từ nhận xét này trong mã nguồn của nó:

Từ điển chung được sao chép từ nguồn của Hashtable

Nguồn


393
Và các bộ sưu tập chung cũng nhanh hơn rất nhiều vì không có quyền anh / unboxing
Chris S

6
Không chắc chắn về Hashtable với tuyên bố trên, nhưng đối với ArrayList vs List <t> đó là sự thật
Chris S

36
Hashtable sử dụng Object để giữ mọi thứ bên trong (Chỉ có cách không chung chung để làm điều đó) nên nó cũng sẽ phải đóng hộp / bỏ hộp.
Guvante

16
@BrianJ: "Bảng băm" (hai từ) là thuật ngữ khoa học máy tính cho loại cấu trúc này; Từ điển là một thực hiện cụ thể. HashTable tương ứng với một từ điển <object, object> (mặc dù có giao diện hơi khác nhau), nhưng cả hai đều là các triển khai của khái niệm bảng băm. Và tất nhiên, chỉ cần nhầm lẫn thêm vấn đề, một số ngôn ngữ gọi bảng băm của họ là "từ điển" (ví dụ Python) - nhưng thuật ngữ CS thích hợp vẫn là bảng băm.
Michael Madsen

32
@BrianJ: Cả HashTable(lớp) và Dictionary(lớp) đều là bảng băm (khái niệm), nhưng a HashTablekhông phải là a Dictionary, cũng không phải là Dictionarya HashTable. Chúng được sử dụng trong thời trang rất giống nhau và Dictionary<Object,Object>có thể hoạt động theo cách tương tự như HashTablevậy, nhưng chúng không trực tiếp chia sẻ bất kỳ mã nào (mặc dù các phần có thể được thực hiện theo cách rất giống nhau).
Michael Madsen

625

Dictionary<<< >>> Hashtablekhác biệt:

  • Chung <<< >>> Không chung
  • Cần đồng bộ hóa luồng riêng <<< >>> Cung cấp phiên bản an toàn của luồng thông qua Synchronized()phương thức
  • Mục đã liệt kê: KeyValuePair<<< >>> Mục đã liệt kê:DictionaryEntry
  • Mới hơn (> .NET 2.0 ) <<< >>> Cũ hơn (kể từ .NET 1.0 )
  • nằm trong System.Collections.Generic <<< >>> nằm trong System.Collections
  • Yêu cầu khóa không tồn tại ném ngoại lệ <<< >>> Yêu cầu khóa không tồn tại trả về null
  • có khả năng nhanh hơn một chút đối với các loại giá trị <<< >>> chậm hơn một chút (cần đóng hộp / bỏ hộp) cho các loại giá trị

Dictionary/ Hashtableđiểm tương đồng:

  • Cả hai đều là hashtables nội bộ == truy cập nhanh vào dữ liệu nhiều mục theo khóa
  • Cả hai đều cần khóa bất biến và duy nhất
  • Chìa khóa của cả hai cần GetHashCode()phương pháp riêng

Các bộ sưu tập .NET tương tự (các ứng cử viên sẽ sử dụng thay vì Dictionary và Hashtable):

  • ConcurrentDictionary- chủ đề an toàn (có thể được truy cập an toàn từ một số chủ đề đồng thời)
  • HybridDictionary- hiệu suất được tối ưu hóa (cho một vài mặt hàng và cũng cho nhiều mặt hàng)
  • OrderedDictionary- các giá trị có thể được truy cập thông qua chỉ mục int (theo thứ tự các mục được thêm vào)
  • SortedDictionary- mục tự động sắp xếp
  • StringDictionary- được gõ mạnh và tối ưu hóa cho chuỗi

11
@ Guillaume86, đây là lý do tại sao bạn sử dụng TryGetValue thay vì msdn.microsoft.com/en-us/l
Trident D'Gao

2
+1 cho StringDictionary... btw StringDictionarykhông giống như Dictionary<string, string>khi bạn sử dụng hàm tạo mặc định.
Cheng Chen

ParallelExtensionsExtras @ code.msdn.microsoft.com/windowsdesktop/ cám chứa một ObservableConcienDixi có khả năng ràng buộc tuyệt vời cũng như đồng thời.
VoteCoffee

3
lời giải thích tuyệt vời, thật tuyệt khi bạn cũng liệt kê những điểm tương đồng để giảm bớt những câu hỏi có thể xuất hiện trong đầu
mkb


178

Bởi vì Dictionarylà một lớp chung ( Dictionary<TKey, TValue>), do đó, việc truy cập nội dung của nó là loại an toàn (nghĩa là bạn không cần truyền từ Object, như bạn làm với a Hashtable).

Đối chiếu

var customers = new Dictionary<string, Customer>();
...
Customer customer = customers["Ali G"];

đến

var customers = new Hashtable();
...
Customer customer = customers["Ali G"] as Customer;

Tuy nhiên, Dictionaryđược thực hiện dưới dạng bảng băm trong nội bộ, vì vậy về mặt kỹ thuật, nó hoạt động theo cùng một cách.


88

FYI: Trong .NET, Hashtableluồng an toàn được sử dụng bởi nhiều luồng người đọc và một luồng viết đơn, trong khi ở Dictionarycác thành viên tĩnh công khai là luồng an toàn, nhưng bất kỳ thành viên thể hiện nào đều không được đảm bảo là luồng an toàn.

Chúng tôi đã phải thay đổi tất cả các từ điển của chúng tôi trở lại Hashtablevì điều này.


10
Vui vẻ. Từ điển <T> mã nguồn trông gọn gàng và nhanh hơn rất nhiều. Có thể tốt hơn để sử dụng Từ điển và thực hiện đồng bộ hóa của riêng bạn. Nếu từ điển đọc hoàn toàn cần phải có tính hiện tại, thì bạn chỉ cần đồng bộ hóa quyền truy cập vào các phương thức đọc / ghi của Từ điển. Nó sẽ là rất nhiều khóa, nhưng nó sẽ chính xác.
Triynko

10
Ngoài ra, nếu số lần đọc của bạn không nhất thiết phải là hiện tại, bạn có thể coi từ điển là bất biến. Sau đó, bạn có thể lấy một tham chiếu đến Từ điển và đạt được hiệu suất bằng cách không đồng bộ hóa các lần đọc (vì nó không thay đổi và an toàn theo chủ đề). Để cập nhật nó, bạn xây dựng một bản sao Từ điển được cập nhật hoàn chỉnh trong nền, sau đó chỉ cần trao đổi tham chiếu với Interlocked.CompareExchange (giả sử một luồng viết đơn; nhiều luồng viết sẽ yêu cầu đồng bộ hóa các bản cập nhật).
Triynko

38
.Net 4.0 đã thêm ConcurrentDictionarylớp có tất cả các phương thức công khai / được bảo vệ được triển khai để an toàn cho luồng. Nếu bạn không cần hỗ trợ các nền tảng cũ, điều này sẽ cho phép bạn thay thế Hashtablemã đa luồng: msdn.microsoft.com/en-us/l Library / dd287191.aspx
Dan Is Fiddling By Firelight

ẩn danh để giải cứu. Câu trả lời tuyệt vời.
unkulunkulu

5
Tôi nhớ lại rằng đọc HashTable chỉ an toàn cho người đọc và người viết trong kịch bản mà thông tin không bao giờ bị xóa khỏi bảng. Nếu một người đọc đang yêu cầu một mục trong bảng trong khi một mục khác đang bị xóa và người đọc sẽ tìm ở nhiều nơi cho mục đó, thì có thể trong khi người đọc đang tìm kiếm thì người viết có thể di chuyển mục đó từ một nơi chưa được kiểm tra đến một nơi có, do đó dẫn đến một báo cáo sai rằng vật phẩm không tồn tại.
supercat

68

Trong .NET, sự khác biệt giữa Dictionary<,>HashTablechủ yếu là trước đây là một loại chung chung, do đó bạn nhận được tất cả các lợi ích của thuốc generic về kiểm tra loại tĩnh (và giảm quyền anh, nhưng điều này không lớn như mọi người thường nghĩ điều khoản về hiệu suất - mặc dù có một chi phí bộ nhớ nhất định cho quyền anh).


34

Mọi người đang nói rằng một từ điển giống như một bảng băm.

Điều này không thực sự đúng. Bảng băm là một cách để thực hiện từ điển. Một điển hình ở đó, và nó có thể là mặc định trong .NET trong Dictionarylớp, nhưng nó không phải là định nghĩa duy nhất.

Bạn cũng có thể triển khai từ điển bằng cách sử dụng danh sách được liên kết hoặc cây tìm kiếm, nó sẽ không hiệu quả (đối với một số chỉ số hiệu quả).


4
Các tài liệu MS nói: "Lấy một giá trị bằng cách sử dụng khóa của nó rất nhanh, gần với O (1), vì lớp Từ điển <(Of <(TKey, TValue>)>) được triển khai dưới dạng bảng băm." - vì vậy bạn nên được đảm bảo một hashtable khi giao dịch Dictionary<K,V>. IDictionary<K,V>có thể là bất cứ điều gì, mặc dù :)
snemarch

13
@ rix0rrr - Tôi nghĩ rằng bạn đã có điều đó ngược lại, Từ điển sử dụng HashTable chứ không phải HashTable sử dụng Từ điển.
Joseph Hamilton

8
@Joseph Hamilton - rix0rrr đã hiểu đúng: "Bảng băm một cách thực hiện của một từ điển ." Ông có nghĩa là khái niệm "từ điển", không phải lớp (lưu ý chữ thường). Về mặt khái niệm, một bảng băm thực hiện một giao diện từ điển. Trong .NET, Dictionary sử dụng bảng băm để triển khai IDadata. Nó lộn xộn;)
Robert Hensing

Tôi đã nói về .NET, vì đó là những gì anh ấy tham khảo trong phản hồi của mình.
Joseph Hamilton

2
@Joseph Hamilton: thực hiện (hoặc thực hiện ) thậm chí không có nghĩa là điều tương tự như việc sử dụng . Hoàn toàn ngược lại. Có lẽ mọi chuyện sẽ rõ ràng hơn nếu ông nói nó hơi khác một chút (nhưng có cùng ý nghĩa): "bảng băm là một cách để thực hiện từ điển". Đó là, nếu bạn muốn chức năng của một từ điển, một cách để làm điều đó (để thực hiện từ điển), là sử dụng một hashtable.
ToolmakerSteve

21

Collections& Genericsrất hữu ích để xử lý nhóm đối tượng. Trong .NET, tất cả các đối tượng bộ sưu tập nằm dưới giao diện IEnumerable, lần lượt có ArrayList(Index-Value))& HashTable(Key-Value). Sau .NET framework 2.0, ArrayList& HashTableđã được thay thế bằng List& Dictionary. Bây giờ, Arraylist& HashTablekhông còn được sử dụng trong các dự án ngày nay.

Đến với sự khác biệt giữa HashTable& Dictionary, Dictionarylà chung trong đó Hastablekhông phải là Chung. Chúng ta có thể thêm bất kỳ loại đối tượng nào HashTable, nhưng trong khi truy xuất, chúng ta cần chuyển nó thành loại yêu cầu. Vì vậy, nó không phải là loại an toàn. Nhưng dictionary, trong khi tự khai báo, chúng ta có thể chỉ định loại khóa và giá trị, do đó không cần phải truyền trong khi truy xuất.

Hãy xem xét một ví dụ:

HashTable

class HashTableProgram
{
    static void Main(string[] args)
    {
        Hashtable ht = new Hashtable();
        ht.Add(1, "One");
        ht.Add(2, "Two");
        ht.Add(3, "Three");
        foreach (DictionaryEntry de in ht)
        {
            int Key = (int)de.Key; //Casting
            string value = de.Value.ToString(); //Casting
            Console.WriteLine(Key + " " + value);
        }

    }
}

Từ điển

class DictionaryProgram
{
    static void Main(string[] args)
    {
        Dictionary<int, string> dt = new Dictionary<int, string>();
        dt.Add(1, "One");
        dt.Add(2, "Two");
        dt.Add(3, "Three");
        foreach (KeyValuePair<int, String> kv in dt)
        {
            Console.WriteLine(kv.Key + " " + kv.Value);
        }
    }
}

2
thay vì chỉ định rõ ràng kiểu dữ liệu cho KeyValuePair, chúng ta có thể sử dụng var. Vì vậy, điều này sẽ làm giảm việc gõ - foreach (var kv in dt) ... chỉ là một gợi ý.
Ron

16

Từ điển:

  • Nó trả về / ném Ngoại lệ nếu chúng ta cố gắng tìm một khóa không tồn tại.

  • Nó nhanh hơn Hashtable vì không có quyền anh và unboxing.

  • Chỉ các thành viên tĩnh công khai là chủ đề an toàn.

  • Từ điển là một loại chung có nghĩa là chúng ta có thể sử dụng nó với bất kỳ loại dữ liệu nào (Khi tạo, phải chỉ định loại dữ liệu cho cả khóa và giá trị).

    Thí dụ: Dictionary<string, string> <NameOfDictionaryVar> = new Dictionary<string, string>();

  • Dictionay là một triển khai Hashtable an toàn kiểu, KeysValuesđược gõ mạnh.

Hashtable:

  • Nó trả về null nếu chúng ta cố gắng tìm một khóa không tồn tại.

  • Nó chậm hơn từ điển vì nó đòi hỏi quyền anh và unboxing.

  • Tất cả các thành viên trong Hashtable đều an toàn cho chủ đề,

  • Hashtable không phải là một loại chung chung,

  • Hashtable là cấu trúc dữ liệu được gõ lỏng lẻo, chúng ta có thể thêm các khóa và giá trị của bất kỳ loại nào.


"Nó trả về / ném Ngoại lệ nếu chúng ta cố gắng tìm một khóa không tồn tại." Không, nếu bạn sử dụngDictionary.TryGetValue
Jim Balter

16

Các kiểm tra mở rộng của Cấu trúc dữ liệu Sử dụng C # bài viết trên MSDN nói rằng đó cũng là một sự khác biệt trong chiến lược giải quyết va chạm :

Lớp Hashtable sử dụng một kỹ thuật gọi là luyện tập lại .

Việc làm lại hoạt động như sau: có một tập hợp các hàm băm khác nhau, H 1 ... H n và khi chèn hoặc lấy một mục từ bảng băm, ban đầu, hàm băm H 1 được sử dụng. Nếu điều này dẫn đến va chạm, H 2 được thử thay thế, và tiếp tục lên đến H n nếu cần.

Từ điển sử dụng một kỹ thuật gọi là chuỗi .

Với việc xử lý lại, trong trường hợp va chạm, hàm băm được tính toán lại và vị trí mới tương ứng với hàm băm được thử. Tuy nhiên, với chuỗi, cấu trúc dữ liệu thứ cấp được sử dụng để giữ bất kỳ va chạm nào . Cụ thể, mỗi vị trí trong Từ điển có một mảng các phần tử ánh xạ tới nhóm đó. Trong trường hợp xảy ra va chạm, phần tử va chạm được thêm vào danh sách của nhóm.


16

Vì .NET Framework 3.5 cũng có một HashSet<T>cung cấp tất cả các ưu điểm Dictionary<TKey, TValue>nếu bạn chỉ cần các khóa và không có giá trị.

Vì vậy, nếu bạn sử dụng a Dictionary<MyType, object>và luôn đặt giá trị nullđể mô phỏng bảng băm an toàn loại, bạn có thể nên xem xét chuyển sang HashSet<T>.


14

Đây Hashtablelà một cấu trúc dữ liệu được gõ lỏng lẻo, vì vậy bạn có thể thêm các khóa và giá trị của bất kỳ loại nào vào Hashtable. Các Dictionarylớp học là một loại an toàn Hashtablethực hiện, và các phím và các giá trị được đánh mạnh. Khi tạo một Dictionarythể hiện, bạn phải chỉ định các kiểu dữ liệu cho cả khóa và giá trị.


11

Lưu ý rằng MSDN nói: lớp "Từ điển <(Of <(TKey, TValue>)>) được triển khai dưới dạng bảng băm ", chứ không phải lớp "Từ điển <(Of <(TKey, TValue>)>)" được thực hiện dưới dạng HashTable "

Từ điển KHÔNG được triển khai dưới dạng HashTable, nhưng nó được triển khai theo khái niệm bảng băm. Việc triển khai không liên quan đến lớp HashTable vì sử dụng Generics, mặc dù bên trong Microsoft có thể đã sử dụng cùng một mã và thay thế các ký hiệu loại Object bằng TKey và TValue.

Trong .NET 1.0 Generics không tồn tại; đây là nơi HashTable và ArrayList ban đầu bắt đầu.


Bạn có thể sửa trích dẫn MSDN đó không? Một cái gì đó bị thiếu hoặc sai; nó không đúng ngữ pháp và hơi khó hiểu.
Peter Mortensen

10

HashTable:

Khóa / giá trị sẽ được chuyển đổi thành một loại đối tượng (quyền anh) trong khi lưu trữ vào heap.

Khóa / giá trị cần được chuyển đổi thành loại mong muốn trong khi đọc từ heap.

Các hoạt động này rất tốn kém. Chúng ta cần tránh đấm bốc / unboxing càng nhiều càng tốt.

Từ điển: Biến thể chung của HashTable.

Không có quyền anh / unboxing. Không cần chuyển đổi.


8

Một đối tượng Hashtable bao gồm các thùng chứa các thành phần của bộ sưu tập. Nhóm là một nhóm các phần tử ảo trong Hashtable, giúp tìm kiếm và truy xuất dễ dàng và nhanh hơn trong hầu hết các bộ sưu tập .

Lớp Dictionary có chức năng tương tự như lớp Hashtable. Từ điển của một loại cụ thể (không phải là Object) có hiệu suất tốt hơn Hashtable cho các loại giá trị vì các yếu tố của Hashtable thuộc loại Object và do đó, quyền anh và unboxing thường xảy ra nếu lưu trữ hoặc truy xuất loại giá trị.

Để đọc thêm: Các loại Bộ sưu tập Từ điển và Từ điển


7

Một sự khác biệt quan trọng khác là Hashtable là luồng an toàn. Hashtable có tính năng an toàn luồng nhiều người đọc / một trình ghi (MR / SW) tích hợp, có nghĩa là Hashtable cho phép MỘT trình ghi cùng với nhiều trình đọc mà không bị khóa.

Trong trường hợp của Từ điển không có chủ đề an toàn; nếu bạn cần an toàn luồng, bạn phải thực hiện đồng bộ hóa của riêng bạn.

Để giải thích thêm:

Hashtable cung cấp một số an toàn luồng thông qua thuộc Synchronizedtính, trả về trình bao bọc an toàn luồng xung quanh bộ sưu tập. Trình bao bọc hoạt động bằng cách khóa toàn bộ bộ sưu tập trên mỗi thao tác thêm hoặc xóa. Do đó, mỗi luồng đang cố truy cập vào bộ sưu tập phải chờ đến lượt để lấy một khóa. Điều này không thể mở rộng và có thể gây suy giảm hiệu suất đáng kể cho các bộ sưu tập lớn. Ngoài ra, thiết kế không hoàn toàn được bảo vệ khỏi các điều kiện chủng tộc.

Các lớp bộ sưu tập .NET Framework 2.0 như List<T>, Dictionary<TKey, TValue>, v.v. không cung cấp bất kỳ đồng bộ hóa luồng nào; mã người dùng phải cung cấp tất cả đồng bộ hóa khi các mục được thêm hoặc xóa trên nhiều luồng đồng thời

Nếu bạn cần loại an toàn cũng như an toàn luồng, hãy sử dụng các lớp bộ sưu tập đồng thời trong .NET Framework. Đọc thêm ở đây .

Một sự khác biệt nữa là khi chúng ta thêm nhiều mục trong Từ điển, thứ tự các mục được thêm sẽ được duy trì. Khi chúng tôi lấy các mục từ Từ điển, chúng tôi sẽ nhận được các bản ghi theo cùng thứ tự chúng tôi đã chèn chúng. Trong khi đó Hashtable không bảo toàn thứ tự chèn.


Theo những gì tôi hiểu, Hashsetđảm bảo an toàn luồng MR / SW trong các tình huống sử dụng không liên quan đến việc xóa . Tôi nghĩ rằng nó có thể được dự định là an toàn MR / SW, nhưng xử lý xóa an toàn làm tăng đáng kể chi phí cho an toàn MR / SW. Mặc dù thiết kế Dictionarycó thể mang lại sự an toàn cho MR / SW với chi phí tối thiểu trong các tình huống không xóa, tôi nghĩ rằng MS muốn tránh coi các kịch bản không xóa là "đặc biệt".
supercat

5

Một sự khác biệt nữa mà tôi có thể tìm ra là:

Chúng tôi không thể sử dụng Từ điển <KT, VT> (generic) với các dịch vụ web. Lý do là không có tiêu chuẩn dịch vụ web hỗ trợ tiêu chuẩn chung.


Chúng tôi có thể sử dụng danh sách chung (Danh sách <chuỗi>) trong dịch vụ web dựa trên xà phòng. Nhưng, chúng tôi không thể sử dụng từ điển (hoặc hashtable) trong dịch vụ web. Tôi nghĩ lý do cho điều này là .net xmlserializer không thể xử lý đối tượng từ điển.
Siddharth

5

Dictionary<> là một loại chung chung và vì vậy nó là loại an toàn.

Bạn có thể chèn bất kỳ loại giá trị nào trong HashTable và điều này đôi khi có thể đưa ra một ngoại lệ. Nhưng Dictionary<int>sẽ chỉ chấp nhận các giá trị nguyên và tương tự Dictionary<string>sẽ chỉ chấp nhận các chuỗi.

Vì vậy, tốt hơn là sử dụng Dictionary<>thay vì HashTable.


0

Trong hầu hết các ngôn ngữ lập trình, từ điển được ưa thích hơn hashtables

Tôi không nghĩ điều này nhất thiết đúng, hầu hết các ngôn ngữ đều có cái này hoặc cái kia, tùy thuộc vào thuật ngữ họ thích .

Tuy nhiên, trong C #, lý do rõ ràng (đối với tôi) là C # HashTables và các thành viên khác của không gian tên System.Collections phần lớn đã lỗi thời. Họ đã có mặt trong c # V1.1. Chúng đã được thay thế từ C # 2.0 bởi các lớp Chung trong không gian tên System.Collections.Generic.


Một trong những lợi thế của hashtable so với từ điển là nếu một khóa không tồn tại trong từ điển, nó sẽ gây ra lỗi. Nếu một khóa không tồn tại trong một hashtable, nó chỉ trả về null.
Bill Norman

Trong C # tôi vẫn sẽ tránh sử dụng System.Collections.Hashtable vì chúng không có lợi thế về thuốc generic. Bạn có thể sử dụng TryGetValue hoặc HasKey của Dictionary nếu bạn không biết liệu khóa có tồn tại hay không.
kristianp

Rất tiếc, không phải HasKey, nên là ContainsKey.
kristianp

-3

Theo những gì tôi thấy bằng cách sử dụng .NET Reflector :

[Serializable, ComVisible(true)]
public abstract class DictionaryBase : IDictionary, ICollection, IEnumerable
{
    // Fields
    private Hashtable hashtable;

    // Methods
    protected DictionaryBase();
    public void Clear();
.
.
.
}
Take note of these lines
// Fields
private Hashtable hashtable;

Vì vậy, chúng ta có thể chắc chắn rằng DictionaryBase sử dụng HashTable trong nội bộ.


16
System.Collections.Generic.Dixi <TKey, TValue> không xuất phát từ DictionaryBase.
snemarch

"Vì vậy, chúng tôi có thể chắc chắn rằng DictionaryBase sử dụng HashTable trong nội bộ." - Điều đó thật tuyệt, nhưng nó không liên quan gì đến câu hỏi.
Jim Balter
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.