KeyedCollection<TKey,TItem> Constructors
Definition
Important
Some information relates to prerelease product that may be substantially modified before it’s released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
Initializes a new instance of the KeyedCollection<TKey,TItem> class.
Overloads
KeyedCollection<TKey,TItem>() |
Initializes a new instance of the KeyedCollection<TKey,TItem> class that uses the default equality comparer. |
KeyedCollection<TKey,TItem>(IEqualityComparer<TKey>) |
Initializes a new instance of the KeyedCollection<TKey,TItem> class that uses the specified equality comparer. |
KeyedCollection<TKey,TItem>(IEqualityComparer<TKey>, Int32) |
Initializes a new instance of the KeyedCollection<TKey,TItem> class that uses the specified equality comparer and creates a lookup dictionary when the specified threshold is exceeded. |
KeyedCollection<TKey,TItem>()
- Source:
- KeyedCollection.cs
- Source:
- KeyedCollection.cs
- Source:
- KeyedCollection.cs
Initializes a new instance of the KeyedCollection<TKey,TItem> class that uses the default equality comparer.
protected:
KeyedCollection();
protected KeyedCollection ();
Protected Sub New ()
Examples
This code example shows the minimum code necessary to derive a collection class from KeyedCollection<TKey,TItem>: overriding the GetKeyForItem method and providing a public constructor that delegates to a base class constructor. The code example also demonstrates many of the properties and methods inherited from KeyedCollection<TKey,TItem> and Collection<T> classes.
The SimpleOrder
class is a very simple requisition list that contains OrderItem
objects, each of which represents a line item in the order. The key of OrderItem
is immutable, an important consideration for classes that derive from KeyedCollection<TKey,TItem>. For a code example that uses mutable keys, see 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
Remarks
A KeyedCollection<TKey,TItem> created with this constructor uses the default generic equality comparer for the type of the key, obtained from EqualityComparer<T>.Default. To specify a different generic equality comparer, use the KeyedCollection<TKey,TItem>(IEqualityComparer<TKey>) constructor or the KeyedCollection<TKey,TItem>(IEqualityComparer<TKey>, Int32) constructor.
By default, the KeyedCollection<TKey,TItem> includes a lookup dictionary that is created when the first item is added. When an item is added to the KeyedCollection<TKey,TItem>, the item's key is extracted once and saved in the lookup dictionary for faster searches. This behavior can be overridden by using the KeyedCollection<TKey,TItem>(IEqualityComparer<TKey>, Int32) constructor and specifying a dictionary creation threshold.
Note
Because the KeyedCollection<TKey,TItem> class is abstract (MustInherit
in Visual Basic), you must derive from it in order to use it. In the constructor for your derived type, call the appropriate KeyedCollection<TKey,TItem> constructor. It is not necessary to expose functionality like the equality comparer or the dictionary creation threshold in your constructors.
This constructor is an O(1) operation.
See also
Applies to
KeyedCollection<TKey,TItem>(IEqualityComparer<TKey>)
- Source:
- KeyedCollection.cs
- Source:
- KeyedCollection.cs
- Source:
- KeyedCollection.cs
Initializes a new instance of the KeyedCollection<TKey,TItem> class that uses the specified equality comparer.
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))
Parameters
- comparer
- IEqualityComparer<TKey>
The implementation of the IEqualityComparer<T> generic interface to use when comparing keys, or null
to use the default equality comparer for the type of the key, obtained from Default.
Remarks
By default, the KeyedCollection<TKey,TItem> includes a lookup dictionary that is created when the first item is added. When an item is added to the KeyedCollection<TKey,TItem>, the item's key is extracted once and saved in the lookup dictionary for faster searches. This behavior can be overridden by using the KeyedCollection<TKey,TItem>(IEqualityComparer<TKey>, Int32) constructor and specifying a dictionary creation threshold.
Note
Because the KeyedCollection<TKey,TItem> class is abstract (MustInherit
in Visual Basic), you must derive from it in order to use it. In the constructor for your derived type, call the appropriate KeyedCollection<TKey,TItem> constructor. It is not necessary to expose functionality like the equality comparer or the dictionary creation threshold in your constructors.
This constructor is an O(1) operation.
See also
Applies to
KeyedCollection<TKey,TItem>(IEqualityComparer<TKey>, Int32)
- Source:
- KeyedCollection.cs
- Source:
- KeyedCollection.cs
- Source:
- KeyedCollection.cs
Initializes a new instance of the KeyedCollection<TKey,TItem> class that uses the specified equality comparer and creates a lookup dictionary when the specified threshold is exceeded.
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)
Parameters
- comparer
- IEqualityComparer<TKey>
The implementation of the IEqualityComparer<T> generic interface to use when comparing keys, or null
to use the default equality comparer for the type of the key, obtained from Default.
- dictionaryCreationThreshold
- Int32
The number of elements the collection can hold without creating a lookup dictionary (0 creates the lookup dictionary when the first item is added), or -1 to specify that a lookup dictionary is never created.
Exceptions
dictionaryCreationThreshold
is less than -1.
Examples
The following code example shows how to override the protected InsertItem, RemoveItem, ClearItems, and SetItem methods, to provide custom behavior for the Add, Remove, and Clear methods, and for setting the default Item[] property (the indexer in C#). The custom behavior provided in this example is a notification event named Changed
, which is raised at the end of each of the overridden methods.
The code example uses the KeyedCollection<TKey,TItem>(IEqualityComparer<TKey>, Int32) constructor with a threshold of 0, so that the internal dictionary is created the first time an object is added to the collection.
The code example creates the SimpleOrder
class, which derives from KeyedCollection<TKey,TItem> and represents a simple order form. The order form contains OrderItem
objects representing items ordered. The code example also creates a SimpleOrderChangedEventArgs
class to contain the event information, and an enumeration to identify the type of change.
The code example demonstrates the custom behavior by calling the properties and methods of the derived class, in the Main
method of the Demo
class.
This code example uses objects with immutable keys. For a code example that uses mutable keys, see 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.
Remarks
By default, the KeyedCollection<TKey,TItem> includes a lookup dictionary that is created when the first item is added. When an item is added to the KeyedCollection<TKey,TItem>, the item's key is extracted once and saved in the lookup dictionary for faster searches. This constructor allows you to override that behavior. Specify 0 to create the dictionary when the first element is added, 1 to create the dictionary when the second element is added, and so on. If you specify -1 as the threshold, the lookup dictionary is never created.
For very small collections the improvement in retrieval speed provided by the lookup dictionary might not be worth the extra memory required by the dictionary. Setting a threshold allows you to decide when to make that tradeoff.
Note
Because the KeyedCollection<TKey,TItem> class is abstract (MustInherit
in Visual Basic), you must derive from it in order to use it. In the constructor for your derived type, call the appropriate KeyedCollection<TKey,TItem> constructor. It is not necessary to expose functionality like the equality comparer or the dictionary creation threshold in your constructors.
This constructor is an O(1) operation.
See also
Applies to
Feedback
https://aka.ms/ContentUserFeedback.
În curând: Pe parcursul anului 2024, vom elimina treptat Probleme legate de GitHub ca mecanism de feedback pentru conținut și îl vom înlocui cu un nou sistem de feedback. Pentru mai multe informații, consultați:Trimiteți și vizualizați feedback pentru