KeyedCollection<TKey,TItem> 构造函数
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
初始化 KeyedCollection<TKey,TItem> 类的新实例。
重载
KeyedCollection<TKey,TItem>() |
初始化使用默认相等比较器的 KeyedCollection<TKey,TItem> 类的新实例。 |
KeyedCollection<TKey,TItem>(IEqualityComparer<TKey>) |
初始化使用指定相等比较器的 KeyedCollection<TKey,TItem> 类的新实例。 |
KeyedCollection<TKey,TItem>(IEqualityComparer<TKey>, Int32) |
初始化 KeyedCollection<TKey,TItem> 类的新实例,该新实例使用指定的相等比较器并在超过指定阈值时创建一个查找字典。 |
KeyedCollection<TKey,TItem>()
- Source:
- KeyedCollection.cs
- Source:
- KeyedCollection.cs
- Source:
- KeyedCollection.cs
初始化使用默认相等比较器的 KeyedCollection<TKey,TItem> 类的新实例。
protected:
KeyedCollection();
protected KeyedCollection ();
Protected Sub New ()
示例
此代码示例演示从 KeyedCollection<TKey,TItem>派生集合类所需的最低代码:重写 GetKeyForItem 方法并提供委托给基类构造函数的公共构造函数。 该代码示例还演示了从 KeyedCollection<TKey,TItem> 和 类继承的许多属性和 Collection<T> 方法。
类 SimpleOrder
是一个非常简单的申请列表,其中包含 OrderItem
对象,其中每个对象都表示顺序中的一个行项。 的关键 OrderItem
是不可变的,这是派生自 KeyedCollection<TKey,TItem>的类的一个重要考虑因素。 有关使用可变键的代码示例,请参阅 ChangeItemKey。
using namespace System;
using namespace System::Collections::Generic;
using namespace System::Collections::ObjectModel;
// This class represents a simple line item in an order. All the
// values are immutable except quantity.
//
public ref class OrderItem
{
private:
int _quantity;
public:
initonly int PartNumber;
initonly String^ Description;
initonly double UnitPrice;
OrderItem(int partNumber, String^ description,
int quantity, double unitPrice)
{
this->PartNumber = partNumber;
this->Description = description;
this->Quantity = quantity;
this->UnitPrice = unitPrice;
}
property int Quantity
{
int get() { return _quantity; }
void set(int value)
{
if (value < 0)
throw gcnew ArgumentException("Quantity cannot be negative.");
_quantity = value;
}
}
virtual String^ ToString() override
{
return String::Format(
"{0,9} {1,6} {2,-12} at {3,8:#,###.00} = {4,10:###,###.00}",
PartNumber, _quantity, Description, UnitPrice,
UnitPrice * _quantity);
}
};
// This class represents a very simple keyed list of OrderItems,
// inheriting most of its behavior from the KeyedCollection and
// Collection classes. The immediate base class is the constructed
// type KeyedCollection<int, OrderItem>. When you inherit
// from KeyedCollection, the second generic type argument is the
// type that you want to store in the collection -- in this case
// OrderItem. The first type argument is the type that you want
// to use as a key. Its values must be calculated from OrderItem;
// in this case it is the int field PartNumber, so SimpleOrder
// inherits KeyedCollection<int, OrderItem>.
//
public ref class SimpleOrder : KeyedCollection<int, OrderItem^>
{
// The parameterless constructor of the base class creates a
// KeyedCollection with an internal dictionary. For this code
// example, no other constructors are exposed.
//
public:
SimpleOrder() {}
// This is the only method that absolutely must be overridden,
// because without it the KeyedCollection cannot extract the
// keys from the items. The input parameter type is the
// second generic type argument, in this case OrderItem, and
// the return value type is the first generic type argument,
// in this case int.
//
protected:
virtual int GetKeyForItem(OrderItem^ item) override
{
// In this example, the key is the part number.
return item->PartNumber;
}
};
public ref class Demo
{
public:
static void Main()
{
SimpleOrder^ weekly = gcnew SimpleOrder();
// The Add method, inherited from Collection, takes OrderItem.
//
weekly->Add(gcnew OrderItem(110072674, "Widget", 400, 45.17));
weekly->Add(gcnew OrderItem(110072675, "Sprocket", 27, 5.3));
weekly->Add(gcnew OrderItem(101030411, "Motor", 10, 237.5));
weekly->Add(gcnew OrderItem(110072684, "Gear", 175, 5.17));
Display(weekly);
// The Contains method of KeyedCollection takes the key,
// type, in this case int.
//
Console::WriteLine("\nContains(101030411): {0}",
weekly->Contains(101030411));
// The default Item property of KeyedCollection takes a key.
//
Console::WriteLine("\nweekly(101030411)->Description: {0}",
weekly[101030411]->Description);
// The Remove method of KeyedCollection takes a key.
//
Console::WriteLine("\nRemove(101030411)");
weekly->Remove(101030411);
Display(weekly);
// The Insert method, inherited from Collection, takes an
// index and an OrderItem.
//
Console::WriteLine("\nInsert(2, New OrderItem(...))");
weekly->Insert(2, gcnew OrderItem(111033401, "Nut", 10, .5));
Display(weekly);
// The default Item property is overloaded. One overload comes
// from KeyedCollection<int, OrderItem>; that overload
// is read-only, and takes Integer because it retrieves by key.
// The other overload comes from Collection<OrderItem>, the
// base class of KeyedCollection<int, OrderItem>; it
// retrieves by index, so it also takes an Integer. The compiler
// uses the most-derived overload, from KeyedCollection, so the
// only way to access SimpleOrder by index is to cast it to
// Collection<OrderItem>. Otherwise the index is interpreted
// as a key, and KeyNotFoundException is thrown.
//
Collection<OrderItem^>^ coweekly = weekly;
Console::WriteLine("\ncoweekly[2].Description: {0}",
coweekly[2]->Description);
Console::WriteLine("\ncoweekly[2] = gcnew OrderItem(...)");
coweekly[2] = gcnew OrderItem(127700026, "Crank", 27, 5.98);
OrderItem^ temp = coweekly[2];
// The IndexOf method inherited from Collection<OrderItem>
// takes an OrderItem instead of a key
//
Console::WriteLine("\nIndexOf(temp): {0}", weekly->IndexOf(temp));
// The inherited Remove method also takes an OrderItem.
//
Console::WriteLine("\nRemove(temp)");
weekly->Remove(temp);
Display(weekly);
Console::WriteLine("\nRemoveAt(0)");
weekly->RemoveAt(0);
Display(weekly);
}
private:
static void Display(SimpleOrder^ order)
{
Console::WriteLine();
for each( OrderItem^ item in order )
{
Console::WriteLine(item);
}
}
};
void main()
{
Demo::Main();
}
/* This code example produces the following output:
110072674 400 Widget at 45.17 = 18,068.00
110072675 27 Sprocket at 5.30 = 143.10
101030411 10 Motor at 237.50 = 2,375.00
110072684 175 Gear at 5.17 = 904.75
Contains(101030411): True
weekly(101030411)->Description: Motor
Remove(101030411)
110072674 400 Widget at 45.17 = 18,068.00
110072675 27 Sprocket at 5.30 = 143.10
110072684 175 Gear at 5.17 = 904.75
Insert(2, New OrderItem(...))
110072674 400 Widget at 45.17 = 18,068.00
110072675 27 Sprocket at 5.30 = 143.10
111033401 10 Nut at .50 = 5.00
110072684 175 Gear at 5.17 = 904.75
coweekly(2)->Description: Nut
coweekly[2] = gcnew OrderItem(...)
IndexOf(temp): 2
Remove(temp)
110072674 400 Widget at 45.17 = 18,068.00
110072675 27 Sprocket at 5.30 = 143.10
110072684 175 Gear at 5.17 = 904.75
RemoveAt(0)
110072675 27 Sprocket at 5.30 = 143.10
110072684 175 Gear at 5.17 = 904.75
*/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
// This class represents a very simple keyed list of OrderItems,
// inheriting most of its behavior from the KeyedCollection and
// Collection classes. The immediate base class is the constructed
// type KeyedCollection<int, OrderItem>. When you inherit
// from KeyedCollection, the second generic type argument is the
// type that you want to store in the collection -- in this case
// OrderItem. The first type argument is the type that you want
// to use as a key. Its values must be calculated from OrderItem;
// in this case it is the int field PartNumber, so SimpleOrder
// inherits KeyedCollection<int, OrderItem>.
//
public class SimpleOrder : KeyedCollection<int, OrderItem>
{
// This is the only method that absolutely must be overridden,
// because without it the KeyedCollection cannot extract the
// keys from the items. The input parameter type is the
// second generic type argument, in this case OrderItem, and
// the return value type is the first generic type argument,
// in this case int.
//
protected override int GetKeyForItem(OrderItem item)
{
// In this example, the key is the part number.
return item.PartNumber;
}
}
public class Demo
{
public static void Main()
{
SimpleOrder weekly = new SimpleOrder();
// The Add method, inherited from Collection, takes OrderItem.
//
weekly.Add(new OrderItem(110072674, "Widget", 400, 45.17));
weekly.Add(new OrderItem(110072675, "Sprocket", 27, 5.3));
weekly.Add(new OrderItem(101030411, "Motor", 10, 237.5));
weekly.Add(new OrderItem(110072684, "Gear", 175, 5.17));
Display(weekly);
// The Contains method of KeyedCollection takes the key,
// type, in this case int.
//
Console.WriteLine("\nContains(101030411): {0}",
weekly.Contains(101030411));
// The default Item property of KeyedCollection takes a key.
//
Console.WriteLine("\nweekly[101030411].Description: {0}",
weekly[101030411].Description);
// The Remove method of KeyedCollection takes a key.
//
Console.WriteLine("\nRemove(101030411)");
weekly.Remove(101030411);
Display(weekly);
// The Insert method, inherited from Collection, takes an
// index and an OrderItem.
//
Console.WriteLine("\nInsert(2, New OrderItem(...))");
weekly.Insert(2, new OrderItem(111033401, "Nut", 10, .5));
Display(weekly);
// The default Item property is overloaded. One overload comes
// from KeyedCollection<int, OrderItem>; that overload
// is read-only, and takes Integer because it retrieves by key.
// The other overload comes from Collection<OrderItem>, the
// base class of KeyedCollection<int, OrderItem>; it
// retrieves by index, so it also takes an Integer. The compiler
// uses the most-derived overload, from KeyedCollection, so the
// only way to access SimpleOrder by index is to cast it to
// Collection<OrderItem>. Otherwise the index is interpreted
// as a key, and KeyNotFoundException is thrown.
//
Collection<OrderItem> coweekly = weekly;
Console.WriteLine("\ncoweekly[2].Description: {0}",
coweekly[2].Description);
Console.WriteLine("\ncoweekly[2] = new OrderItem(...)");
coweekly[2] = new OrderItem(127700026, "Crank", 27, 5.98);
OrderItem temp = coweekly[2];
// The IndexOf method inherited from Collection<OrderItem>
// takes an OrderItem instead of a key
//
Console.WriteLine("\nIndexOf(temp): {0}", weekly.IndexOf(temp));
// The inherited Remove method also takes an OrderItem.
//
Console.WriteLine("\nRemove(temp)");
weekly.Remove(temp);
Display(weekly);
Console.WriteLine("\nRemoveAt(0)");
weekly.RemoveAt(0);
Display(weekly);
}
private static void Display(SimpleOrder order)
{
Console.WriteLine();
foreach( OrderItem item in order )
{
Console.WriteLine(item);
}
}
}
// This class represents a simple line item in an order. All the
// values are immutable except quantity.
//
public class OrderItem
{
public readonly int PartNumber;
public readonly string Description;
public readonly double UnitPrice;
private int _quantity = 0;
public OrderItem(int partNumber, string description,
int quantity, double unitPrice)
{
this.PartNumber = partNumber;
this.Description = description;
this.Quantity = quantity;
this.UnitPrice = unitPrice;
}
public int Quantity
{
get { return _quantity; }
set
{
if (value<0)
throw new ArgumentException("Quantity cannot be negative.");
_quantity = value;
}
}
public override string ToString()
{
return String.Format(
"{0,9} {1,6} {2,-12} at {3,8:#,###.00} = {4,10:###,###.00}",
PartNumber, _quantity, Description, UnitPrice,
UnitPrice * _quantity);
}
}
/* This code example produces the following output:
110072674 400 Widget at 45.17 = 18,068.00
110072675 27 Sprocket at 5.30 = 143.10
101030411 10 Motor at 237.50 = 2,375.00
110072684 175 Gear at 5.17 = 904.75
Contains(101030411): True
weekly[101030411].Description: Motor
Remove(101030411)
110072674 400 Widget at 45.17 = 18,068.00
110072675 27 Sprocket at 5.30 = 143.10
110072684 175 Gear at 5.17 = 904.75
Insert(2, New OrderItem(...))
110072674 400 Widget at 45.17 = 18,068.00
110072675 27 Sprocket at 5.30 = 143.10
111033401 10 Nut at .50 = 5.00
110072684 175 Gear at 5.17 = 904.75
coweekly[2].Description: Nut
coweekly[2] = new OrderItem(...)
IndexOf(temp): 2
Remove(temp)
110072674 400 Widget at 45.17 = 18,068.00
110072675 27 Sprocket at 5.30 = 143.10
110072684 175 Gear at 5.17 = 904.75
RemoveAt(0)
110072675 27 Sprocket at 5.30 = 143.10
110072684 175 Gear at 5.17 = 904.75
*/
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
' This class represents a very simple keyed list of OrderItems,
' inheriting most of its behavior from the KeyedCollection and
' Collection classes. The immediate base class is the constructed
' type KeyedCollection(Of Integer, OrderItem). When you inherit
' from KeyedCollection, the second generic type argument is the
' type that you want to store in the collection -- in this case
' OrderItem. The first generic argument is the type that you want
' to use as a key. Its values must be calculated from OrderItem;
' in this case it is the Integer field PartNumber, so SimpleOrder
' inherits KeyedCollection(Of Integer, OrderItem).
'
Public Class SimpleOrder
Inherits KeyedCollection(Of Integer, OrderItem)
' This is the only method that absolutely must be overridden,
' because without it the KeyedCollection cannot extract the
' keys from the items. The input parameter type is the
' second generic type argument, in this case OrderItem, and
' the return value type is the first generic type argument,
' in this case Integer.
'
Protected Overrides Function GetKeyForItem( _
ByVal item As OrderItem) As Integer
' In this example, the key is the part number.
Return item.PartNumber
End Function
End Class
Public Class Demo
Public Shared Sub Main()
Dim weekly As New SimpleOrder()
' The Add method, inherited from Collection, takes OrderItem.
'
weekly.Add(New OrderItem(110072674, "Widget", 400, 45.17))
weekly.Add(New OrderItem(110072675, "Sprocket", 27, 5.3))
weekly.Add(New OrderItem(101030411, "Motor", 10, 237.5))
weekly.Add(New OrderItem(110072684, "Gear", 175, 5.17))
Display(weekly)
' The Contains method of KeyedCollection takes TKey.
'
Console.WriteLine(vbLf & "Contains(101030411): {0}", _
weekly.Contains(101030411))
' The default Item property of KeyedCollection takes the key
' type, Integer.
'
Console.WriteLine(vbLf & "weekly(101030411).Description: {0}", _
weekly(101030411).Description)
' The Remove method of KeyedCollection takes a key.
'
Console.WriteLine(vbLf & "Remove(101030411)")
weekly.Remove(101030411)
Display(weekly)
' The Insert method, inherited from Collection, takes an
' index and an OrderItem.
'
Console.WriteLine(vbLf & "Insert(2, New OrderItem(...))")
weekly.Insert(2, New OrderItem(111033401, "Nut", 10, .5))
Display(weekly)
' The default Item property is overloaded. One overload comes
' from KeyedCollection(Of Integer, OrderItem); that overload
' is read-only, and takes Integer because it retrieves by key.
' The other overload comes from Collection(Of OrderItem), the
' base class of KeyedCollection(Of Integer, OrderItem); it
' retrieves by index, so it also takes an Integer. The compiler
' uses the most-derived overload, from KeyedCollection, so the
' only way to access SimpleOrder by index is to cast it to
' Collection(Of OrderItem). Otherwise the index is interpreted
' as a key, and KeyNotFoundException is thrown.
'
Dim coweekly As Collection(Of OrderItem) = weekly
Console.WriteLine(vbLf & "coweekly(2).Description: {0}", _
coweekly(2).Description)
Console.WriteLine(vbLf & "coweekly(2) = New OrderItem(...)")
coweekly(2) = New OrderItem(127700026, "Crank", 27, 5.98)
Dim temp As OrderItem = coweekly(2)
' The IndexOf method, inherited from Collection(Of OrderItem),
' takes an OrderItem instead of a key.
'
Console.WriteLine(vbLf & "IndexOf(temp): {0}", _
weekly.IndexOf(temp))
' The inherited Remove method also takes an OrderItem.
'
Console.WriteLine(vbLf & "Remove(temp)")
weekly.Remove(temp)
Display(weekly)
Console.WriteLine(vbLf & "RemoveAt(0)")
weekly.RemoveAt(0)
Display(weekly)
End Sub
Private Shared Sub Display(ByVal order As SimpleOrder)
Console.WriteLine()
For Each item As OrderItem In order
Console.WriteLine(item)
Next item
End Sub
End Class
' This class represents a simple line item in an order. All the
' values are immutable except quantity.
'
Public Class OrderItem
Public ReadOnly PartNumber As Integer
Public ReadOnly Description As String
Public ReadOnly UnitPrice As Double
Private _quantity As Integer = 0
Public Sub New(ByVal partNumber As Integer, _
ByVal description As String, _
ByVal quantity As Integer, _
ByVal unitPrice As Double)
Me.PartNumber = partNumber
Me.Description = description
Me.Quantity = quantity
Me.UnitPrice = unitPrice
End Sub
Public Property Quantity() As Integer
Get
Return _quantity
End Get
Set
If value < 0 Then
Throw New ArgumentException("Quantity cannot be negative.")
End If
_quantity = value
End Set
End Property
Public Overrides Function ToString() As String
Return String.Format( _
"{0,9} {1,6} {2,-12} at {3,8:#,###.00} = {4,10:###,###.00}", _
PartNumber, _quantity, Description, UnitPrice, _
UnitPrice * _quantity)
End Function
End Class
' This code example produces the following output:
'
'110072674 400 Widget at 45.17 = 18,068.00
'110072675 27 Sprocket at 5.30 = 143.10
'101030411 10 Motor at 237.50 = 2,375.00
'110072684 175 Gear at 5.17 = 904.75
'
'Contains(101030411): True
'
'weekly(101030411).Description: Motor
'
'Remove(101030411)
'
'110072674 400 Widget at 45.17 = 18,068.00
'110072675 27 Sprocket at 5.30 = 143.10
'110072684 175 Gear at 5.17 = 904.75
'
'Insert(2, New OrderItem(...))
'
'110072674 400 Widget at 45.17 = 18,068.00
'110072675 27 Sprocket at 5.30 = 143.10
'111033401 10 Nut at .50 = 5.00
'110072684 175 Gear at 5.17 = 904.75
'
'coweekly(2).Description: Nut
'
'coweekly(2) = New OrderItem(...)
'
'IndexOf(temp): 2
'
'Remove(temp)
'
'110072674 400 Widget at 45.17 = 18,068.00
'110072675 27 Sprocket at 5.30 = 143.10
'110072684 175 Gear at 5.17 = 904.75
'
'RemoveAt(0)
'
'110072675 27 Sprocket at 5.30 = 143.10
'110072684 175 Gear at 5.17 = 904.75
注解
KeyedCollection<TKey,TItem>使用此构造函数创建的 对从 EqualityComparer<T>.Default获取的键类型使用默认的泛型相等比较器。 若要指定不同的泛型相等比较器,请使用 KeyedCollection<TKey,TItem>(IEqualityComparer<TKey>) 构造函数或 KeyedCollection<TKey,TItem>(IEqualityComparer<TKey>, Int32) 构造函数。
默认情况下, KeyedCollection<TKey,TItem> 包含添加第一项时创建的查找字典。 将项添加到 KeyedCollection<TKey,TItem>时,该项的键将提取一次并保存在查找字典中,以便更快地进行搜索。 可以使用 构造函数并指定字典创建阈值来重写 KeyedCollection<TKey,TItem>(IEqualityComparer<TKey>, Int32) 此行为。
注意
由于 类 KeyedCollection<TKey,TItem> 是 Visual Basic) MustInherit
中的抽象 (,因此必须从它派生才能使用它。 在派生类型的构造函数中,调用相应的 KeyedCollection<TKey,TItem> 构造函数。 无需在构造函数中公开相等比较器或字典创建阈值等功能。
此构造函数是 O (1) 操作。
另请参阅
适用于
KeyedCollection<TKey,TItem>(IEqualityComparer<TKey>)
- Source:
- KeyedCollection.cs
- Source:
- KeyedCollection.cs
- Source:
- KeyedCollection.cs
初始化使用指定相等比较器的 KeyedCollection<TKey,TItem> 类的新实例。
protected:
KeyedCollection(System::Collections::Generic::IEqualityComparer<TKey> ^ comparer);
protected KeyedCollection (System.Collections.Generic.IEqualityComparer<TKey> comparer);
protected KeyedCollection (System.Collections.Generic.IEqualityComparer<TKey>? comparer);
new System.Collections.ObjectModel.KeyedCollection<'Key, 'Item> : System.Collections.Generic.IEqualityComparer<'Key> -> System.Collections.ObjectModel.KeyedCollection<'Key, 'Item>
Protected Sub New (comparer As IEqualityComparer(Of TKey))
参数
- comparer
- IEqualityComparer<TKey>
比较键时要使用的 IEqualityComparer<T> 泛型接口的实现,如果为 null
,则使用从 Default 获取的该类型的键的默认相等比较器。
注解
默认情况下, KeyedCollection<TKey,TItem> 包含添加第一项时创建的查找字典。 将项添加到 KeyedCollection<TKey,TItem>时,该项的键将提取一次并保存在查找字典中,以便更快地进行搜索。 可以使用 构造函数并指定字典创建阈值来重写 KeyedCollection<TKey,TItem>(IEqualityComparer<TKey>, Int32) 此行为。
注意
由于 类 KeyedCollection<TKey,TItem> 是 Visual Basic) MustInherit
中的抽象 (,因此必须从它派生才能使用它。 在派生类型的构造函数中,调用相应的 KeyedCollection<TKey,TItem> 构造函数。 无需在构造函数中公开相等比较器或字典创建阈值等功能。
此构造函数是 O (1) 操作。
另请参阅
适用于
KeyedCollection<TKey,TItem>(IEqualityComparer<TKey>, Int32)
- Source:
- KeyedCollection.cs
- Source:
- KeyedCollection.cs
- Source:
- KeyedCollection.cs
初始化 KeyedCollection<TKey,TItem> 类的新实例,该新实例使用指定的相等比较器并在超过指定阈值时创建一个查找字典。
protected:
KeyedCollection(System::Collections::Generic::IEqualityComparer<TKey> ^ comparer, int dictionaryCreationThreshold);
protected KeyedCollection (System.Collections.Generic.IEqualityComparer<TKey> comparer, int dictionaryCreationThreshold);
protected KeyedCollection (System.Collections.Generic.IEqualityComparer<TKey>? comparer, int dictionaryCreationThreshold);
new System.Collections.ObjectModel.KeyedCollection<'Key, 'Item> : System.Collections.Generic.IEqualityComparer<'Key> * int -> System.Collections.ObjectModel.KeyedCollection<'Key, 'Item>
Protected Sub New (comparer As IEqualityComparer(Of TKey), dictionaryCreationThreshold As Integer)
参数
- comparer
- IEqualityComparer<TKey>
比较键时要使用的 IEqualityComparer<T> 泛型接口的实现,如果为 null
,则使用从 Default 获取的该类型的键的默认相等比较器。
- dictionaryCreationThreshold
- Int32
在不创建查找字典的情况下集合可容纳的元素的数目(0 表示添加第一项时创建查找字典);或者为 -1,表示指定永远不会创建查找字典。
例外
dictionaryCreationThreshold
小于 -1。
示例
下面的代码示例演示如何重写受保护的 、、 和 方法,以便为 Add、 Remove和 Clear 方法提供自定义行为,以及如何在 C#) 中 (索引器设置默认Item[]属性。SetItemClearItemsRemoveItemInsertItem 此示例中提供的自定义行为是一个名为 的 Changed
通知事件,该事件在每个重写的方法的末尾引发。
该代码示例使用 KeyedCollection<TKey,TItem>(IEqualityComparer<TKey>, Int32) 阈值为 0 的构造函数,以便在首次将对象添加到集合时创建内部字典。
该代码示例创建 SimpleOrder
类,该类派生自 KeyedCollection<TKey,TItem> 并表示简单的订单形式。 订单窗体包含 OrderItem
表示已排序项的对象。 该代码示例还创建一个 SimpleOrderChangedEventArgs
类来包含事件信息,并创建一个枚举来标识更改的类型。
代码示例通过在 类的 方法中 Main
调用派生类的属性和方法 Demo
来演示自定义行为。
此代码示例使用具有不可变键的对象。 有关使用可变键的代码示例,请参阅 ChangeItemKey。
using namespace System;
using namespace System::Collections::Generic;
using namespace System::Collections::ObjectModel;
public enum class ChangeTypes
{
Added,
Removed,
Replaced,
Cleared
};
ref class SimpleOrderChangedEventArgs;
// This class represents a simple line item in an order. All the
// values are immutable except quantity.
//
public ref class OrderItem
{
private:
int _quantity;
public:
initonly int PartNumber;
initonly String^ Description;
initonly double UnitPrice;
OrderItem(int partNumber, String^ description, int quantity,
double unitPrice)
{
this->PartNumber = partNumber;
this->Description = description;
this->Quantity = quantity;
this->UnitPrice = unitPrice;
};
property int Quantity
{
int get() { return _quantity; };
void set(int value)
{
if (value < 0)
throw gcnew ArgumentException("Quantity cannot be negative.");
_quantity = value;
};
};
virtual String^ ToString() override
{
return String::Format(
"{0,9} {1,6} {2,-12} at {3,8:#,###.00} = {4,10:###,###.00}",
PartNumber, _quantity, Description, UnitPrice,
UnitPrice * _quantity);
};
};
// Event argument for the Changed event.
//
public ref class SimpleOrderChangedEventArgs : EventArgs
{
public:
OrderItem^ ChangedItem;
initonly ChangeTypes ChangeType;
OrderItem^ ReplacedWith;
SimpleOrderChangedEventArgs(ChangeTypes change,
OrderItem^ item, OrderItem^ replacement)
{
this->ChangeType = change;
this->ChangedItem = item;
this->ReplacedWith = replacement;
}
};
// This class derives from KeyedCollection and shows how to override
// the protected ClearItems, InsertItem, RemoveItem, and SetItem
// methods in order to change the behavior of the default Item
// property and the Add, Clear, Insert, and Remove methods. The
// class implements a Changed event, which is raised by all the
// protected methods.
//
// SimpleOrder is a collection of OrderItem objects, and its key
// is the PartNumber field of OrderItem-> PartNumber is an Integer,
// so SimpleOrder inherits KeyedCollection<int, OrderItem>.
// (Note that the key of OrderItem cannot be changed; if it could
// be changed, SimpleOrder would have to override ChangeItemKey.)
//
public ref class SimpleOrder : KeyedCollection<int, OrderItem^>
{
public:
event EventHandler<SimpleOrderChangedEventArgs^>^ Changed;
// This parameterless constructor calls the base class constructor
// that specifies a dictionary threshold of 0, so that the internal
// dictionary is created as soon as an item is added to the
// collection.
//
SimpleOrder() : KeyedCollection<int, OrderItem^>(nullptr, 0) {};
// This is the only method that absolutely must be overridden,
// because without it the KeyedCollection cannot extract the
// keys from the items.
//
protected:
virtual int GetKeyForItem(OrderItem^ item) override
{
// In this example, the key is the part number.
return item->PartNumber;
}
virtual void InsertItem(int index, OrderItem^ newItem) override
{
__super::InsertItem(index, newItem);
Changed(this, gcnew SimpleOrderChangedEventArgs(
ChangeTypes::Added, newItem, nullptr));
}
virtual void SetItem(int index, OrderItem^ newItem) override
{
OrderItem^ replaced = this->Items[index];
__super::SetItem(index, newItem);
Changed(this, gcnew SimpleOrderChangedEventArgs(
ChangeTypes::Replaced, replaced, newItem));
}
virtual void RemoveItem(int index) override
{
OrderItem^ removedItem = Items[index];
__super::RemoveItem(index);
Changed(this, gcnew SimpleOrderChangedEventArgs(
ChangeTypes::Removed, removedItem, nullptr));
}
virtual void ClearItems() override
{
__super::ClearItems();
Changed(this, gcnew SimpleOrderChangedEventArgs(
ChangeTypes::Cleared, nullptr, nullptr));
}
// This method uses the internal reference to the dictionary
// to test fo
public:
void AddOrMerge(OrderItem^ newItem)
{
int key = this->GetKeyForItem(newItem);
OrderItem^ existingItem = nullptr;
// The dictionary is not created until the first item is
// added, so it is necessary to test for null. Using
// AndAlso ensures that TryGetValue is not called if the
// dictionary does not exist.
//
if (this->Dictionary != nullptr &&
this->Dictionary->TryGetValue(key, existingItem))
{
existingItem->Quantity += newItem->Quantity;
}
else
{
this->Add(newItem);
}
}
};
public ref class Demo
{
public:
static void Main()
{
SimpleOrder^ weekly = gcnew SimpleOrder();
weekly->Changed += gcnew
EventHandler<SimpleOrderChangedEventArgs^>(ChangedHandler);
// The Add method, inherited from Collection, takes OrderItem->
//
weekly->Add(gcnew OrderItem(110072674, "Widget", 400, 45.17));
weekly->Add(gcnew OrderItem(110072675, "Sprocket", 27, 5.3));
weekly->Add(gcnew OrderItem(101030411, "Motor", 10, 237.5));
weekly->Add(gcnew OrderItem(110072684, "Gear", 175, 5.17));
Display(weekly);
// The Contains method of KeyedCollection takes TKey.
//
Console::WriteLine("\nContains(101030411): {0}",
weekly->Contains(101030411));
// The default Item property of KeyedCollection takes the key
// type, Integer. The property is read-only.
//
Console::WriteLine("\nweekly[101030411]->Description: {0}",
weekly[101030411]->Description);
// The Remove method of KeyedCollection takes a key.
//
Console::WriteLine("\nRemove(101030411)");
weekly->Remove(101030411);
// The Insert method, inherited from Collection, takes an
// index and an OrderItem.
//
Console::WriteLine("\nInsert(2, gcnew OrderItem(...))");
weekly->Insert(2, gcnew OrderItem(111033401, "Nut", 10, .5));
// The default Item property is overloaded. One overload comes
// from KeyedCollection<int, OrderItem>; that overload
// is read-only, and takes Integer because it retrieves by key.
// The other overload comes from Collection<OrderItem>, the
// base class of KeyedCollection<int, OrderItem>; it
// retrieves by index, so it also takes an Integer. The compiler
// uses the most-derived overload, from KeyedCollection, so the
// only way to access SimpleOrder by index is to cast it to
// Collection<OrderItem>. Otherwise the index is interpreted
// as a key, and KeyNotFoundException is thrown.
//
Collection<OrderItem^>^ coweekly = weekly;
Console::WriteLine("\ncoweekly[2].Description: {0}",
coweekly[2]->Description);
Console::WriteLine("\ncoweekly[2] = gcnew OrderItem(...)");
coweekly[2] = gcnew OrderItem(127700026, "Crank", 27, 5.98);
OrderItem^ temp = coweekly[2];
// The IndexOf method, inherited from Collection<OrderItem>,
// takes an OrderItem instead of a key.
//
Console::WriteLine("\nIndexOf(temp): {0}", weekly->IndexOf(temp));
// The inherited Remove method also takes an OrderItem->
//
Console::WriteLine("\nRemove(temp)");
weekly->Remove(temp);
Console::WriteLine("\nRemoveAt(0)");
weekly->RemoveAt(0);
weekly->AddOrMerge(gcnew OrderItem(110072684, "Gear", 1000, 5.17));
Display(weekly);
Console::WriteLine();
weekly->Clear();
}
private:
static void Display(SimpleOrder^ order)
{
Console::WriteLine();
for each( OrderItem^ item in order )
{
Console::WriteLine(item);
}
}
static void ChangedHandler(Object^ source,
SimpleOrderChangedEventArgs^ e)
{
OrderItem^ item = e->ChangedItem;
if (e->ChangeType == ChangeTypes::Replaced)
{
OrderItem^ replacement = e->ReplacedWith;
Console::WriteLine("{0} (quantity {1}) was replaced " +
"by {2}, (quantity {3}).", item->Description,
item->Quantity, replacement->Description,
replacement->Quantity);
}
else if(e->ChangeType == ChangeTypes::Cleared)
{
Console::WriteLine("The order list was cleared.");
}
else
{
Console::WriteLine("{0} (quantity {1}) was {2}.",
item->Description, item->Quantity, e->ChangeType);
}
}
};
void main()
{
Demo::Main();
}
/* This code example produces the following output:
Widget (quantity 400) was Added.
Sprocket (quantity 27) was Added.
Motor (quantity 10) was Added.
Gear (quantity 175) was Added.
110072674 400 Widget at 45.17 = 18,068.00
110072675 27 Sprocket at 5.30 = 143.10
101030411 10 Motor at 237.50 = 2,375.00
110072684 175 Gear at 5.17 = 904.75
Contains(101030411): True
weekly[101030411]->Description: Motor
Remove(101030411)
Motor (quantity 10) was Removed.
Insert(2, gcnew OrderItem(...))
Nut (quantity 10) was Added.
coweekly[2].Description: Nut
coweekly[2] = gcnew OrderItem(...)
Nut (quantity 10) was replaced by Crank, (quantity 27).
IndexOf(temp): 2
Remove(temp)
Crank (quantity 27) was Removed.
RemoveAt(0)
Widget (quantity 400) was Removed.
110072675 27 Sprocket at 5.30 = 143.10
110072684 1175 Gear at 5.17 = 6,074.75
The order list was cleared.
*/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
// This class derives from KeyedCollection and shows how to override
// the protected ClearItems, InsertItem, RemoveItem, and SetItem
// methods in order to change the behavior of the default Item
// property and the Add, Clear, Insert, and Remove methods. The
// class implements a Changed event, which is raised by all the
// protected methods.
//
// SimpleOrder is a collection of OrderItem objects, and its key
// is the PartNumber field of OrderItem. PartNumber is an Integer,
// so SimpleOrder inherits KeyedCollection<int, OrderItem>.
// (Note that the key of OrderItem cannot be changed; if it could
// be changed, SimpleOrder would have to override ChangeItemKey.)
//
public class SimpleOrder : KeyedCollection<int, OrderItem>
{
public event EventHandler<SimpleOrderChangedEventArgs> Changed;
// This parameterless constructor calls the base class constructor
// that specifies a dictionary threshold of 0, so that the internal
// dictionary is created as soon as an item is added to the
// collection.
//
public SimpleOrder() : base(null, 0) {}
// This is the only method that absolutely must be overridden,
// because without it the KeyedCollection cannot extract the
// keys from the items.
//
protected override int GetKeyForItem(OrderItem item)
{
// In this example, the key is the part number.
return item.PartNumber;
}
protected override void InsertItem(int index, OrderItem newItem)
{
base.InsertItem(index, newItem);
EventHandler<SimpleOrderChangedEventArgs> temp = Changed;
if (temp != null)
{
temp(this, new SimpleOrderChangedEventArgs(
ChangeType.Added, newItem, null));
}
}
protected override void SetItem(int index, OrderItem newItem)
{
OrderItem replaced = Items[index];
base.SetItem(index, newItem);
EventHandler<SimpleOrderChangedEventArgs> temp = Changed;
if (temp != null)
{
temp(this, new SimpleOrderChangedEventArgs(
ChangeType.Replaced, replaced, newItem));
}
}
protected override void RemoveItem(int index)
{
OrderItem removedItem = Items[index];
base.RemoveItem(index);
EventHandler<SimpleOrderChangedEventArgs> temp = Changed;
if (temp != null)
{
temp(this, new SimpleOrderChangedEventArgs(
ChangeType.Removed, removedItem, null));
}
}
protected override void ClearItems()
{
base.ClearItems();
EventHandler<SimpleOrderChangedEventArgs> temp = Changed;
if (temp != null)
{
temp(this, new SimpleOrderChangedEventArgs(
ChangeType.Cleared, null, null));
}
}
}
// Event argument for the Changed event.
//
public class SimpleOrderChangedEventArgs : EventArgs
{
private OrderItem _changedItem;
private ChangeType _changeType;
private OrderItem _replacedWith;
public OrderItem ChangedItem { get { return _changedItem; }}
public ChangeType ChangeType { get { return _changeType; }}
public OrderItem ReplacedWith { get { return _replacedWith; }}
public SimpleOrderChangedEventArgs(ChangeType change,
OrderItem item, OrderItem replacement)
{
_changeType = change;
_changedItem = item;
_replacedWith = replacement;
}
}
public enum ChangeType
{
Added,
Removed,
Replaced,
Cleared
};
public class Demo
{
public static void Main()
{
SimpleOrder weekly = new SimpleOrder();
weekly.Changed += new
EventHandler<SimpleOrderChangedEventArgs>(ChangedHandler);
// The Add method, inherited from Collection, takes OrderItem.
//
weekly.Add(new OrderItem(110072674, "Widget", 400, 45.17));
weekly.Add(new OrderItem(110072675, "Sprocket", 27, 5.3));
weekly.Add(new OrderItem(101030411, "Motor", 10, 237.5));
weekly.Add(new OrderItem(110072684, "Gear", 175, 5.17));
Display(weekly);
// The Contains method of KeyedCollection takes TKey.
//
Console.WriteLine("\nContains(101030411): {0}",
weekly.Contains(101030411));
// The default Item property of KeyedCollection takes the key
// type, Integer. The property is read-only.
//
Console.WriteLine("\nweekly[101030411].Description: {0}",
weekly[101030411].Description);
// The Remove method of KeyedCollection takes a key.
//
Console.WriteLine("\nRemove(101030411)");
weekly.Remove(101030411);
// The Insert method, inherited from Collection, takes an
// index and an OrderItem.
//
Console.WriteLine("\nInsert(2, new OrderItem(...))");
weekly.Insert(2, new OrderItem(111033401, "Nut", 10, .5));
// The default Item property is overloaded. One overload comes
// from KeyedCollection<int, OrderItem>; that overload
// is read-only, and takes Integer because it retrieves by key.
// The other overload comes from Collection<OrderItem>, the
// base class of KeyedCollection<int, OrderItem>; it
// retrieves by index, so it also takes an Integer. The compiler
// uses the most-derived overload, from KeyedCollection, so the
// only way to access SimpleOrder by index is to cast it to
// Collection<OrderItem>. Otherwise the index is interpreted
// as a key, and KeyNotFoundException is thrown.
//
Collection<OrderItem> coweekly = weekly;
Console.WriteLine("\ncoweekly[2].Description: {0}",
coweekly[2].Description);
Console.WriteLine("\ncoweekly[2] = new OrderItem(...)");
coweekly[2] = new OrderItem(127700026, "Crank", 27, 5.98);
OrderItem temp = coweekly[2];
// The IndexOf method, inherited from Collection<OrderItem>,
// takes an OrderItem instead of a key.
//
Console.WriteLine("\nIndexOf(temp): {0}", weekly.IndexOf(temp));
// The inherited Remove method also takes an OrderItem.
//
Console.WriteLine("\nRemove(temp)");
weekly.Remove(temp);
Console.WriteLine("\nRemoveAt(0)");
weekly.RemoveAt(0);
// Increase the quantity for a line item.
Console.WriteLine("\ncoweekly(1) = New OrderItem(...)");
coweekly[1] = new OrderItem(coweekly[1].PartNumber,
coweekly[1].Description, coweekly[1].Quantity + 1000,
coweekly[1].UnitPrice);
Display(weekly);
Console.WriteLine();
weekly.Clear();
}
private static void Display(SimpleOrder order)
{
Console.WriteLine();
foreach( OrderItem item in order )
{
Console.WriteLine(item);
}
}
private static void ChangedHandler(object source,
SimpleOrderChangedEventArgs e)
{
OrderItem item = e.ChangedItem;
if (e.ChangeType==ChangeType.Replaced)
{
OrderItem replacement = e.ReplacedWith;
Console.WriteLine("{0} (quantity {1}) was replaced " +
"by {2}, (quantity {3}).", item.Description,
item.Quantity, replacement.Description,
replacement.Quantity);
}
else if(e.ChangeType == ChangeType.Cleared)
{
Console.WriteLine("The order list was cleared.");
}
else
{
Console.WriteLine("{0} (quantity {1}) was {2}.",
item.Description, item.Quantity, e.ChangeType);
}
}
}
// This class represents a simple line item in an order. All the
// values are immutable except quantity.
//
public class OrderItem
{
private int _partNumber;
private string _description;
private double _unitPrice;
private int _quantity;
public int PartNumber { get { return _partNumber; }}
public string Description { get { return _description; }}
public double UnitPrice { get { return _unitPrice; }}
public int Quantity { get { return _quantity; }}
public OrderItem(int partNumber, string description, int quantity,
double unitPrice)
{
_partNumber = partNumber;
_description = description;
_quantity = quantity;
_unitPrice = unitPrice;
}
public override string ToString()
{
return String.Format(
"{0,9} {1,6} {2,-12} at {3,8:#,###.00} = {4,10:###,###.00}",
PartNumber, _quantity, Description, UnitPrice,
UnitPrice * _quantity);
}
}
/* This code example produces the following output:
Widget (quantity 400) was Added.
Sprocket (quantity 27) was Added.
Motor (quantity 10) was Added.
Gear (quantity 175) was Added.
110072674 400 Widget at 45.17 = 18,068.00
110072675 27 Sprocket at 5.30 = 143.10
101030411 10 Motor at 237.50 = 2,375.00
110072684 175 Gear at 5.17 = 904.75
Contains(101030411): True
weekly[101030411].Description: Motor
Remove(101030411)
Motor (quantity 10) was Removed.
Insert(2, new OrderItem(...))
Nut (quantity 10) was Added.
coweekly[2].Description: Nut
coweekly[2] = new OrderItem(...)
Nut (quantity 10) was replaced by Crank, (quantity 27).
IndexOf(temp): 2
Remove(temp)
Crank (quantity 27) was Removed.
RemoveAt(0)
Widget (quantity 400) was Removed.
coweekly(1) = New OrderItem(...)
Gear (quantity 175) was replaced by Gear, (quantity 1175).
110072675 27 Sprocket at 5.30 = 143.10
110072684 1175 Gear at 5.17 = 6,074.75
The order list was cleared.
*/
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
' This class derives from KeyedCollection and shows how to override
' the protected ClearItems, InsertItem, RemoveItem, and SetItem
' methods in order to change the behavior of the default Item
' property and the Add, Clear, Insert, and Remove methods. The
' class implements a Changed event, which is raised by all the
' protected methods.
'
' SimpleOrder is a collection of OrderItem objects, and its key
' is the PartNumber field of OrderItem. PartNumber is an Integer,
' so SimpleOrder inherits KeyedCollection(Of Integer, OrderItem).
' (Note that the key of OrderItem cannot be changed; if it could
' be changed, SimpleOrder would have to override ChangeItemKey.)
'
Public Class SimpleOrder
Inherits KeyedCollection(Of Integer, OrderItem)
Public Event Changed As EventHandler(Of SimpleOrderChangedEventArgs)
' This parameterless constructor calls the base class constructor
' that specifies a dictionary threshold of 0, so that the internal
' dictionary is created as soon as an item is added to the
' collection.
'
Public Sub New()
MyBase.New(Nothing, 0)
End Sub
' This is the only method that absolutely must be overridden,
' because without it the KeyedCollection cannot extract the
' keys from the items.
'
Protected Overrides Function GetKeyForItem( _
ByVal item As OrderItem) As Integer
' In this example, the key is the part number.
Return item.PartNumber
End Function
Protected Overrides Sub InsertItem( _
ByVal index As Integer, ByVal newItem As OrderItem)
MyBase.InsertItem(index, newItem)
RaiseEvent Changed(Me, New SimpleOrderChangedEventArgs( _
ChangeType.Added, newItem, Nothing))
End Sub
Protected Overrides Sub SetItem(ByVal index As Integer, _
ByVal newItem As OrderItem)
Dim replaced As OrderItem = Items(index)
MyBase.SetItem(index, newItem)
RaiseEvent Changed(Me, New SimpleOrderChangedEventArgs( _
ChangeType.Replaced, replaced, newItem))
End Sub
Protected Overrides Sub RemoveItem(ByVal index As Integer)
Dim removedItem As OrderItem = Items(index)
MyBase.RemoveItem(index)
RaiseEvent Changed(Me, New SimpleOrderChangedEventArgs( _
ChangeType.Removed, removedItem, Nothing))
End Sub
Protected Overrides Sub ClearItems()
MyBase.ClearItems()
RaiseEvent Changed(Me, New SimpleOrderChangedEventArgs( _
ChangeType.Cleared, Nothing, Nothing))
End Sub
End Class
' Event argument for the Changed event.
'
Public Class SimpleOrderChangedEventArgs
Inherits EventArgs
Private _changedItem As OrderItem
Private _changeType As ChangeType
Private _replacedWith As OrderItem
Public ReadOnly Property ChangedItem As OrderItem
Get
Return _changedItem
End Get
End Property
Public ReadOnly Property ChangeType As ChangeType
Get
Return _changeType
End Get
End Property
Public ReadOnly Property ReplacedWith As OrderItem
Get
Return _replacedWith
End Get
End Property
Public Sub New(ByVal change As ChangeType, ByVal item As OrderItem, _
ByVal replacement As OrderItem)
_changeType = change
_changedItem = item
_replacedWith = replacement
End Sub
End Class
Public Enum ChangeType
Added
Removed
Replaced
Cleared
End Enum
Public Class Demo
Public Shared Sub Main()
Dim weekly As New SimpleOrder()
AddHandler weekly.Changed, AddressOf ChangedHandler
' The Add method, inherited from Collection, takes OrderItem.
'
weekly.Add(New OrderItem(110072674, "Widget", 400, 45.17))
weekly.Add(New OrderItem(110072675, "Sprocket", 27, 5.3))
weekly.Add(New OrderItem(101030411, "Motor", 10, 237.5))
weekly.Add(New OrderItem(110072684, "Gear", 175, 5.17))
Display(weekly)
' The Contains method of KeyedCollection takes TKey.
'
Console.WriteLine(vbLf & "Contains(101030411): {0}", _
weekly.Contains(101030411))
' The default Item property of KeyedCollection takes the key
' type, Integer. The property is read-only.
'
Console.WriteLine(vbLf & "weekly(101030411).Description: {0}", _
weekly(101030411).Description)
' The Remove method of KeyedCollection takes a key.
'
Console.WriteLine(vbLf & "Remove(101030411)")
weekly.Remove(101030411)
' The Insert method, inherited from Collection, takes an
' index and an OrderItem.
'
Console.WriteLine(vbLf & "Insert(2, New OrderItem(...))")
weekly.Insert(2, New OrderItem(111033401, "Nut", 10, .5))
' The default Item property is overloaded. One overload comes
' from KeyedCollection(Of Integer, OrderItem); that overload
' is read-only, and takes Integer because it retrieves by key.
' The other overload comes from Collection(Of OrderItem), the
' base class of KeyedCollection(Of Integer, OrderItem); it
' retrieves by index, so it also takes an Integer. The compiler
' uses the most-derived overload, from KeyedCollection, so the
' only way to access SimpleOrder by index is to cast it to
' Collection(Of OrderItem). Otherwise the index is interpreted
' as a key, and KeyNotFoundException is thrown.
'
Dim coweekly As Collection(Of OrderItem) = weekly
Console.WriteLine(vbLf & "coweekly(2).Description: {0}", _
coweekly(2).Description)
Console.WriteLine(vbLf & "coweekly(2) = New OrderItem(...)")
coweekly(2) = New OrderItem(127700026, "Crank", 27, 5.98)
Dim temp As OrderItem = coweekly(2)
' The IndexOf method, inherited from Collection(Of OrderItem),
' takes an OrderItem instead of a key.
'
Console.WriteLine(vbLf & "IndexOf(temp): {0}", _
weekly.IndexOf(temp))
' The inherited Remove method also takes an OrderItem.
'
Console.WriteLine(vbLf & "Remove(temp)")
weekly.Remove(temp)
Console.WriteLine(vbLf & "RemoveAt(0)")
weekly.RemoveAt(0)
' Increase the quantity for a line item.
Console.WriteLine(vbLf & "coweekly(1) = New OrderItem(...)")
coweekly(1) = New OrderItem(coweekly(1).PartNumber, _
coweekly(1).Description, coweekly(1).Quantity + 1000, _
coweekly(1).UnitPrice)
Display(weekly)
Console.WriteLine()
weekly.Clear()
End Sub
Private Shared Sub Display(ByVal order As SimpleOrder)
Console.WriteLine()
For Each item As OrderItem In order
Console.WriteLine(item)
Next item
End Sub
Private Shared Sub ChangedHandler(ByVal source As Object, _
ByVal e As SimpleOrderChangedEventArgs)
Dim item As OrderItem = e.ChangedItem
If e.ChangeType = ChangeType.Replaced Then
Dim replacement As OrderItem = e.ReplacedWith
Console.WriteLine("{0} (quantity {1}) was replaced " & _
"by {2}, (quantity {3}).", item.Description, _
item.Quantity, replacement.Description, replacement.Quantity)
ElseIf e.ChangeType = ChangeType.Cleared Then
Console.WriteLine("The order list was cleared.")
Else
Console.WriteLine("{0} (quantity {1}) was {2}.", _
item.Description, item.Quantity, e.ChangeType)
End If
End Sub
End Class
' This class represents a simple line item in an order. All the
' values are immutable except quantity.
'
Public Class OrderItem
Private _partNumber As Integer
Private _description As String
Private _unitPrice As Double
Private _quantity As Integer
Public ReadOnly Property PartNumber As Integer
Get
Return _partNumber
End Get
End Property
Public ReadOnly Property Description As String
Get
Return _description
End Get
End Property
Public ReadOnly Property UnitPrice As Double
Get
Return _unitPrice
End Get
End Property
Public ReadOnly Property Quantity() As Integer
Get
Return _quantity
End Get
End Property
Public Sub New(ByVal partNumber As Integer, _
ByVal description As String, _
ByVal quantity As Integer, _
ByVal unitPrice As Double)
_partNumber = partNumber
_description = description
_quantity = quantity
_unitPrice = unitPrice
End Sub
Public Overrides Function ToString() As String
Return String.Format( _
"{0,9} {1,6} {2,-12} at {3,8:#,###.00} = {4,10:###,###.00}", _
PartNumber, _quantity, Description, UnitPrice, _
UnitPrice * _quantity)
End Function
End Class
' This code example produces the following output:
'
'Widget (quantity 400) was Added.
'Sprocket (quantity 27) was Added.
'Motor (quantity 10) was Added.
'Gear (quantity 175) was Added.
'
'110072674 400 Widget at 45.17 = 18,068.00
'110072675 27 Sprocket at 5.30 = 143.10
'101030411 10 Motor at 237.50 = 2,375.00
'110072684 175 Gear at 5.17 = 904.75
'
'Contains(101030411): True
'
'weekly(101030411).Description: Motor
'
'Remove(101030411)
'Motor (quantity 10) was Removed.
'
'Insert(2, New OrderItem(...))
'Nut (quantity 10) was Added.
'
'coweekly(2).Description: Nut
'
'coweekly(2) = New OrderItem(...)
'Nut (quantity 10) was replaced by Crank, (quantity 27).
'
'IndexOf(temp): 2
'
'Remove(temp)
'Crank (quantity 27) was Removed.
'
'RemoveAt(0)
'Widget (quantity 400) was Removed.
'
'coweekly(1) = New OrderItem(...)
'Gear (quantity 175) was replaced by Gear, (quantity 1175).
'
'110072675 27 Sprocket at 5.30 = 143.10
'110072684 1175 Gear at 5.17 = 6,074.75
'
'The order list was cleared.
注解
默认情况下, KeyedCollection<TKey,TItem> 包含添加第一项时创建的查找字典。 将项添加到 KeyedCollection<TKey,TItem>时,该项的键将提取一次并保存在查找字典中,以便更快地进行搜索。 此构造函数允许重写该行为。 指定 0 在添加第一个元素时创建字典,指定 1 在添加第二个元素时创建字典,依此指定。 如果指定 -1 作为阈值,则永远不会创建查找字典。
对于非常小的集合,查找字典提供的检索速度改进可能不值得字典所需的额外内存。 设置阈值可以决定何时进行权衡。
注意
由于 类 KeyedCollection<TKey,TItem> 是 Visual Basic) MustInherit
中的抽象 (,因此必须从它派生才能使用它。 在派生类型的构造函数中,调用相应的 KeyedCollection<TKey,TItem> 构造函数。 无需在构造函数中公开相等比较器或字典创建阈值等功能。
此构造函数是 O (1) 操作。