注意:這個類別是 .NET Framework 2.0 版的新功能。
表示索引鍵和值的集合。
命名空間: System.Collections.Generic
組件: mscorlib (在 mscorlib.dll 中)
<SerializableAttribute> _
<ComVisibleAttribute(False)> _
Public Class Dictionary(Of TKey, TValue)
Implements IDictionary(Of TKey, TValue), ICollection(Of KeyValuePair(Of TKey, TValue)), _
IEnumerable(Of KeyValuePair(Of TKey, TValue)), IDictionary, ICollection, _
IEnumerable, ISerializable, IDeserializationCallback
Dim instance As Dictionary(Of TKey, TValue)
[SerializableAttribute]
[ComVisibleAttribute(false)]
public class Dictionary<TKey,TValue> : IDictionary<TKey,TValue>, ICollection<KeyValuePair<TKey,TValue>>,
IEnumerable<KeyValuePair<TKey,TValue>>, IDictionary, ICollection, IEnumerable,
ISerializable, IDeserializationCallback
[SerializableAttribute]
[ComVisibleAttribute(false)]
generic<typename TKey, typename TValue>
public ref class Dictionary : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>,
IEnumerable<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, IEnumerable,
ISerializable, IDeserializationCallback
J# 可以支援使用泛型型別和方法,但不允許宣告新的泛型型別和方法。
型別參數
- TKey
字典中的索引鍵型別。
- TValue
字典中的值型別。
Dictionary 泛型類別提供從一組索引鍵至一組值的對應。加入字典中的每一個項目都是由值及其關聯索引鍵所組成。使用其索引鍵擷取值的速度非常快 (接近 O(1)),這是因為 Dictionary 類別是實作為雜湊資料表。
注意事項 |
|---|
| 擷取速度取決於為 TKey 指定之型別的雜湊演算法品質。 |
只要物件用做 Dictionary 中的索引鍵,就無法以影響其雜湊值 (Hash Value) 的任何方式對其進行變更。Dictionary 中的每個索引鍵都必須是唯一的 (根據字典的相等比較子 (Comparer))。索引鍵不能是 Null 參照 (即 Visual Basic 中的 Nothing),但是,如果值型別 TValue 是參考型別時,值就可以是 Null。
Dictionary 需要相等實作,以判斷索引鍵是否相等。藉由使用接受 comparer 參數的建構函式 (Constructor),您可以指定 IEqualityComparer 泛型介面的實作。如果您不指定實作,則會使用預設的泛型相等比較子 EqualityComparer.Default。如果型別 TKey 會實作 System.IEquatable 泛型介面,則預設相等比較子會使用該實作。
Dictionary 的容量是 Dictionary 可以保存的項目數目。在這個實作中,Dictionary 的預設初始容量為 3,但該預設值在未來的 .NET Framework 版本中可能會變更。隨著元素逐漸加入 Dictionary 內,也會視需要透過重新配置內部陣列的方式自動增加容量。
為了列舉型別的用途,會將字典中的每一個項目都視為表示一個值及其索引鍵的 KeyValuePair 結構。未定義項目的傳回順序。
C# 語言 (在 C++ 中為 for each;在 Visual Basic 中為 For Each) 的 foreach 陳述式需要集合中每個項目的型別。因為 Dictionary 是索引鍵和值的集合,所以項目型別不是索引鍵的型別或值的型別。相反,項目型別為索引鍵型別和實值型別的 KeyValuePair。例如:
foreach (KeyValuePair<int, string> kvp in myDictionary) {...}
for each (KeyValuePair<int, String^> kvp in myDictionary) {...}
For Each kvp As KeyValuePair(Of Integer, String) In myDictionary
...
Next kvp
foreach 陳述式是列舉值周圍的包裝函式,它只允許從集合讀取,而不允許寫入集合。
下列程式碼範例建立了具有字串索引鍵之字串的空白 Dictionary,並使用 Add 方法加入部分項目。此範例示範當嘗試加入重複的索引鍵時,Add 方法會擲回 ArgumentException。
此範例使用 Item 屬性 (在 C# 中為索引子) 擷取值,並示範所要求的索引鍵不存在時,會擲回 KeyNotFoundException,並且顯示與索引鍵關聯的值可以被取代。
該範例顯示如果程式必須經常嘗試字典中不存在的索引鍵值,如何使用 TryGetValue 這個更有效率的方法擷取值,還顯示如何先使用 ContainsKey 方法測試索引鍵是否存在,然後再呼叫 Add 方法。
該範例示範如何列舉字典中的索引鍵和值,以及如何使用 Keys 屬性和 Values 屬性單獨列舉索引鍵和值。
最後,範例會示範 Remove 方法。
Imports System
Imports System.Collections.Generic
Public Class Example
Public Shared Sub Main()
' Create a new dictionary of strings, with string keys.
'
Dim openWith As New Dictionary(Of String, String)
' Add some elements to the dictionary. There are no
' duplicate keys, but some of the values are duplicates.
openWith.Add("txt", "notepad.exe")
openWith.Add("bmp", "paint.exe")
openWith.Add("dib", "paint.exe")
openWith.Add("rtf", "wordpad.exe")
' The Add method throws an exception if the new key is
' already in the dictionary.
Try
openWith.Add("txt", "winword.exe")
Catch
Console.WriteLine("An element with Key = ""txt"" already exists.")
End Try
' The Item property is the default property, so you
' can omit its name when accessing elements.
Console.WriteLine("For key = ""rtf"", value = {0}.", _
openWith("rtf"))
' The default Item property can be used to change the value
' associated with a key.
openWith("rtf") = "winword.exe"
Console.WriteLine("For key = ""rtf"", value = {0}.", _
openWith("rtf"))
' If a key does not exist, setting the default Item property
' for that key adds a new key/value pair.
openWith("doc") = "winword.exe"
' The default Item property throws an exception if the requested
' key is not in the dictionary.
Try
Console.WriteLine("For key = ""tif"", value = {0}.", _
openWith("tif"))
Catch
Console.WriteLine("Key = ""tif"" is not found.")
End Try
' When a program often has to try keys that turn out not to
' be in the dictionary, TryGetValue can be a more efficient
' way to retrieve values.
Dim value As String = ""
If openWith.TryGetValue("tif", value) Then
Console.WriteLine("For key = ""tif"", value = {0}.", value)
Else
Console.WriteLine("Key = ""tif"" is not found.")
End If
' ContainsKey can be used to test keys before inserting
' them.
If Not openWith.ContainsKey("ht") Then
openWith.Add("ht", "hypertrm.exe")
Console.WriteLine("Value added for key = ""ht"": {0}", _
openWith("ht"))
End If
' When you use foreach to enumerate dictionary elements,
' the elements are retrieved as KeyValuePair objects.
Console.WriteLine()
For Each kvp As KeyValuePair(Of String, String) In openWith
Console.WriteLine("Key = {0}, Value = {1}", _
kvp.Key, kvp.Value)
Next kvp
' To get the values alone, use the Values property.
Dim valueColl As _
Dictionary(Of String, String).ValueCollection = _
openWith.Values
' The elements of the ValueCollection are strongly typed
' with the type that was specified for dictionary values.
Console.WriteLine()
For Each s As String In valueColl
Console.WriteLine("Value = {0}", s)
Next s
' To get the keys alone, use the Keys property.
Dim keyColl As _
Dictionary(Of String, String).KeyCollection = _
openWith.Keys
' The elements of the KeyCollection are strongly typed
' with the type that was specified for dictionary keys.
Console.WriteLine()
For Each s As String In keyColl
Console.WriteLine("Key = {0}", s)
Next s
' Use the Remove method to remove a key/value pair.
Console.WriteLine(vbLf + "Remove(""doc"")")
openWith.Remove("doc")
If Not openWith.ContainsKey("doc") Then
Console.WriteLine("Key ""doc"" is not found.")
End If
End Sub
End Class
' This code example produces the following output:
'
'An element with Key = "txt" already exists.
'For key = "rtf", value = wordpad.exe.
'For key = "rtf", value = winword.exe.
'Key = "tif" is not found.
'Key = "tif" is not found.
'Value added for key = "ht": hypertrm.exe
'
'Key = txt, Value = notepad.exe
'Key = bmp, Value = paint.exe
'Key = dib, Value = paint.exe
'Key = rtf, Value = winword.exe
'Key = doc, Value = winword.exe
'Key = ht, Value = hypertrm.exe
'
'Value = notepad.exe
'Value = paint.exe
'Value = paint.exe
'Value = winword.exe
'Value = winword.exe
'Value = hypertrm.exe
'
'Key = txt
'Key = bmp
'Key = dib
'Key = rtf
'Key = doc
'Key = ht
'
'Remove("doc")
'Key "doc" is not found.
'
using System;
using System.Collections.Generic;
public class Example
{
public static void Main()
{
// Create a new dictionary of strings, with string keys.
//
Dictionary<string, string> openWith =
new Dictionary<string, string>();
// Add some elements to the dictionary. There are no
// duplicate keys, but some of the values are duplicates.
openWith.Add("txt", "notepad.exe");
openWith.Add("bmp", "paint.exe");
openWith.Add("dib", "paint.exe");
openWith.Add("rtf", "wordpad.exe");
// The Add method throws an exception if the new key is
// already in the dictionary.
try
{
openWith.Add("txt", "winword.exe");
}
catch (ArgumentException)
{
Console.WriteLine("An element with Key = \"txt\" already exists.");
}
// The Item property is another name for the indexer, so you
// can omit its name when accessing elements.
Console.WriteLine("For key = \"rtf\", value = {0}.",
openWith["rtf"]);
// The indexer can be used to change the value associated
// with a key.
openWith["rtf"] = "winword.exe";
Console.WriteLine("For key = \"rtf\", value = {0}.",
openWith["rtf"]);
// If a key does not exist, setting the indexer for that key
// adds a new key/value pair.
openWith["doc"] = "winword.exe";
// The indexer throws an exception if the requested key is
// not in the dictionary.
try
{
Console.WriteLine("For key = \"tif\", value = {0}.",
openWith["tif"]);
}
catch (KeyNotFoundException)
{
Console.WriteLine("Key = \"tif\" is not found.");
}
// When a program often has to try keys that turn out not to
// be in the dictionary, TryGetValue can be a more efficient
// way to retrieve values.
string value = "";
if (openWith.TryGetValue("tif", out value))
{
Console.WriteLine("For key = \"tif\", value = {0}.", value);
}
else
{
Console.WriteLine("Key = \"tif\" is not found.");
}
// ContainsKey can be used to test keys before inserting
// them.
if (!openWith.ContainsKey("ht"))
{
openWith.Add("ht", "hypertrm.exe");
Console.WriteLine("Value added for key = \"ht\": {0}",
openWith["ht"]);
}
// When you use foreach to enumerate dictionary elements,
// the elements are retrieved as KeyValuePair objects.
Console.WriteLine();
foreach( KeyValuePair<string, string> kvp in openWith )
{
Console.WriteLine("Key = {0}, Value = {1}",
kvp.Key, kvp.Value);
}
// To get the values alone, use the Values property.
Dictionary<string, string>.ValueCollection valueColl =
openWith.Values;
// The elements of the ValueCollection are strongly typed
// with the type that was specified for dictionary values.
Console.WriteLine();
foreach( string s in valueColl )
{
Console.WriteLine("Value = {0}", s);
}
// To get the keys alone, use the Keys property.
Dictionary<string, string>.KeyCollection keyColl =
openWith.Keys;
// The elements of the KeyCollection are strongly typed
// with the type that was specified for dictionary keys.
Console.WriteLine();
foreach( string s in keyColl )
{
Console.WriteLine("Key = {0}", s);
}
// Use the Remove method to remove a key/value pair.
Console.WriteLine("\nRemove(\"doc\")");
openWith.Remove("doc");
if (!openWith.ContainsKey("doc"))
{
Console.WriteLine("Key \"doc\" is not found.");
}
}
}
/* This code example produces the following output:
An element with Key = "txt" already exists.
For key = "rtf", value = wordpad.exe.
For key = "rtf", value = winword.exe.
Key = "tif" is not found.
Key = "tif" is not found.
Value added for key = "ht": hypertrm.exe
Key = txt, Value = notepad.exe
Key = bmp, Value = paint.exe
Key = dib, Value = paint.exe
Key = rtf, Value = winword.exe
Key = doc, Value = winword.exe
Key = ht, Value = hypertrm.exe
Value = notepad.exe
Value = paint.exe
Value = paint.exe
Value = winword.exe
Value = winword.exe
Value = hypertrm.exe
Key = txt
Key = bmp
Key = dib
Key = rtf
Key = doc
Key = ht
Remove("doc")
Key "doc" is not found.
*/
System.Object
System.Collections.Generic.Dictionary
這個型別的公用 (Public) 靜態 (在 Visual Basic 中為 Shared) 成員為執行緒安全。不保證任何執行個體成員是安全執行緒。
只要未修改集合,Dictionary 可同時支援多個讀取器 (Reader)。即便如此,透過集合的列舉基本上並非安全的執行緒程序。在極少數情況下,列舉型別會和寫入權限相衝突,所以必須在整個列舉期間鎖定集合。若要讓多重執行緒能夠存取集合以便進行讀取和寫入,您必須實作自己的同步處理。
Windows 98、 Windows 2000 SP4、 Windows CE、 Windows Millennium Edition、 Windows Mobile for Pocket PC、 Windows Mobile for Smartphone、 Windows Server 2003、 Windows XP Media Center Edition、 Windows XP Professional x64 Edition、 Windows XP SP2、 Windows XP Starter Edition
.NET Framework 並不支援各種平台的所有版本。如需支援平台版本的相關資訊,請參閱系統需求一節的內容。
.NET Framework
支援版本:2.0
.NET Compact Framework
支援版本:2.0