更新:2007 年 11 月
命名空間:
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# 支援使用泛型 API,但不支援新 API 的宣告。
型別參數
- TKey
字典中的索引鍵型別。
- TValue
字典中的值型別。
Dictionary<(Of <(TKey, TValue>)>) 泛型類別提供從一組索引鍵至一組值的對應。加入字典中的每一個項目都是由值及其關聯索引鍵所組成。使用其索引鍵擷取值的速度非常快 (接近 O(1)),這是因為 Dictionary<(Of <(TKey, TValue>)>) 類別是實作為雜湊資料表。
注意事項: |
|---|
擷取速度取決於為 TKey 指定之型別的雜湊演算法品質。 |
只要物件用做 Dictionary<(Of <(TKey, TValue>)>) 中的索引鍵,就無法以影響其雜湊值 (Hash Value) 的任何方式對其進行變更。Dictionary<(Of <(TKey, TValue>)>) 中的每個索引鍵都必須是唯一的 (根據字典的相等比較子 (Comparer))。索引鍵不能是 nullNothingnullptrNull 參照 (即 Visual Basic 中的 Nothing),但是,如果實值型別 TValue 是參考型別時,值就可以是 Null。
Dictionary<(Of <(TKey, TValue>)>) 需要相等實作,以判斷索引鍵是否相等。藉由使用接受 comparer 參數的建構函式 (Constructor),您可以指定 IEqualityComparer<(Of <(T>)>) 泛型介面的實作。如果您不指定實作,則會使用預設的泛型相等比較子 EqualityComparer<(Of <(T>)>)..::.Default。如果型別 TKey 會實作 System..::.IEquatable<(Of <(T>)>) 泛型介面,則預設相等比較子會使用該實作。
Dictionary<(Of <(TKey, TValue>)>) 的容量是 Dictionary<(Of <(TKey, TValue>)>) 可以保存的項目數目。當項目加入至 Dictionary<(Of <(TKey, TValue>)>) 時,容量會依需要藉由重新配置內部陣列而自動增加。
為了列舉型別的用途,會將字典中的每一個項目都視為表示一個值及其索引鍵的 KeyValuePair<(Of <(TKey, TValue>)>) 結構。未定義項目的傳回順序。
C# 語言 (在 C++ 中為 for each;在 Visual Basic 中為 For Each) 的 foreach 陳述式需要集合中每個項目的型別。因為 Dictionary<(Of <(TKey, TValue>)>) 是索引鍵和值的集合,所以項目型別不是索引鍵的型別或值的型別。相反,項目型別為索引鍵型別和實值型別的 KeyValuePair<(Of <(TKey, TValue>)>)。例如:
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 陳述式是列舉值周圍的包裝函式,它只允許從集合讀取,而不允許寫入集合。
注意事項: |
|---|
由於索引鍵可以繼承,而且其行為已變更,所以比較作業無法使用 Equals 方法來保證其絕對的唯一性。 |
下列程式碼範例建立了具有字串索引鍵之字串的空白 Dictionary<(Of <(TKey, TValue>)>),並使用 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<(Of <(TKey, TValue>)>)
這個型別的公用 (Public) 靜態 (在 Visual Basic 中為 Shared) 成員為執行緒安全。不保證任何執行個體成員是安全執行緒。
只要未修改集合,Dictionary<(Of <(TKey, TValue>)>) 可同時支援多個讀取器 (Reader)。即便如此,透過集合的列舉基本上並非安全的執行緒程序。在極少數情況下,列舉型別會和寫入權限相衝突,所以必須在整個列舉期間鎖定集合。若要讓多重執行緒能夠存取集合以便進行讀取和寫入,您必須實作自己的同步處理。
Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98, Windows CE, Windows Mobile for Smartphone, Windows Mobile for Pocket PC, Xbox 360
.NET Framework 和 .NET Compact Framework 並不支援各種平台的所有版本。如需支援平台版本的相關資訊,請參閱 .NET Framework 系統需求。
.NET Framework
支援版本:3.5、3.0、2.0
.NET Compact Framework
支援版本:3.5、2.0
XNA Framework
支援版本:2.0、1.0
參考