KeyedCollection<TKey,TItem> 类

定义

提供键嵌入在值中的集合的抽象基类。

generic <typename TKey, typename TItem>
public ref class KeyedCollection abstract : System::Collections::ObjectModel::Collection<TItem>
public abstract class KeyedCollection<TKey,TItem> : System.Collections.ObjectModel.Collection<TItem>
[System.Runtime.InteropServices.ComVisible(false)]
[System.Serializable]
public abstract class KeyedCollection<TKey,TItem> : System.Collections.ObjectModel.Collection<TItem>
type KeyedCollection<'Key, 'Item> = class
    inherit Collection<'Item>
[<System.Runtime.InteropServices.ComVisible(false)>]
[<System.Serializable>]
type KeyedCollection<'Key, 'Item> = class
    inherit Collection<'Item>
Public MustInherit Class KeyedCollection(Of TKey, TItem)
Inherits Collection(Of TItem)

类型参数

TKey

集合中的键的类型。

TItem

集合中的项的类型。

继承
Collection<TItem>
KeyedCollection<TKey,TItem>
派生
属性

示例

本部分包含两个代码示例。 第一个示例演示从 KeyedCollection<TKey,TItem>派生所需的最低代码,并演示了许多继承的方法。 第二个示例演示如何重写 的受保护方法 KeyedCollection<TKey,TItem> 以提供自定义行为。

示例 1

此代码示例演示从 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

示例 2

下面的代码示例演示如何重写受保护的 、、 和 方法,以便为 AddRemoveClear 方法提供自定义行为,以及如何在 C#) 中 (索引器设置默认Item[]属性。SetItemClearItemsRemoveItemInsertItem 此示例中提供的自定义行为是一个名为 Changed的通知事件,该事件在每个重写的方法的末尾引发。

代码示例创建 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> 提供 O (1) 索引检索和接近 O (1) 的键式检索。 它是一个抽象类型,或者更准确地说是一组无限的抽象类型,因为它的每个构造泛型类型都是一个抽象基类。 若要使用 KeyedCollection<TKey,TItem>,请从适当的构造类型派生集合类型。

KeyedCollection<TKey,TItem> 是基于泛型接口的 IList<T> 集合与基于泛型接口的 IDictionary<TKey,TValue> 集合之间的混合类。 与基于泛型接口的 IList<T> 集合一样, KeyedCollection<TKey,TItem> 是项的索引列表。 与基于泛型接口的 IDictionary<TKey,TValue> 集合一样, KeyedCollection<TKey,TItem> 具有与每个元素关联的键。

与字典不同, 的 KeyedCollection<TKey,TItem> 元素不是键/值对;相反,整个元素是 值,键嵌入到 值中。 例如,从 Visual Basic) 中的 (KeyedCollection(Of String, String) 派生的KeyedCollection\<String,String>集合的元素可能是“John Doe Jr”。,其值为“John Doe Jr.”,键为“Doe”;或者包含整数键的员工记录的集合可能派生自 KeyedCollection\<int,Employee>。 抽象 GetKeyForItem 方法从 元素中提取键。

默认情况下, KeyedCollection<TKey,TItem> 包含一个可通过 属性获取的 Dictionary 查找字典。 将项添加到 KeyedCollection<TKey,TItem>时,该项的键将提取一次并保存在查找字典中,以便更快地进行搜索。 创建 时,通过指定字典创建阈值来重写此 KeyedCollection<TKey,TItem>行为。 查找字典是在首次元素数超过该阈值时创建的。 如果指定 -1 作为阈值,则永远不会创建查找字典。

注意

使用内部查找字典时,如果 是引用类型,则包含对集合中所有项的引用;如果 TItemTItem 是值类型,则包含集合中所有项的副本。 因此,如果 TItem 是值类型,则使用查找字典可能不适用。

可以使用 属性按项的索引或键 Item[] 来访问项。 可以在没有键的情况下添加项,但随后只能通过索引访问这些项。

构造函数

KeyedCollection<TKey,TItem>()

初始化使用默认相等比较器的 KeyedCollection<TKey,TItem> 类的新实例。

KeyedCollection<TKey,TItem>(IEqualityComparer<TKey>)

初始化使用指定相等比较器的 KeyedCollection<TKey,TItem> 类的新实例。

KeyedCollection<TKey,TItem>(IEqualityComparer<TKey>, Int32)

初始化 KeyedCollection<TKey,TItem> 类的新实例,该新实例使用指定的相等比较器并在超过指定阈值时创建一个查找字典。

属性

Comparer

获取用于确定集合中的键是否相等的泛型相等比较器。

Count

获取 Collection<T> 中实际包含的元素数。

(继承自 Collection<T>)
Dictionary

获取 KeyedCollection<TKey,TItem> 的查找字典。

Item[Int32]

获取或设置指定索引处的元素。

(继承自 Collection<T>)
Item[TKey]

获取具有指定键的元素。

Items

获取 IList<T> 周围的 Collection<T> 包装。

(继承自 Collection<T>)

方法

Add(T)

将对象添加到 Collection<T> 的结尾处。

(继承自 Collection<T>)
ChangeItemKey(TItem, TKey)

更改与查找字典中指定元素相关联的键。

Clear()

Collection<T> 中移除所有元素。

(继承自 Collection<T>)
ClearItems()

KeyedCollection<TKey,TItem> 中移除所有元素。

Contains(TKey)

确定集合是否包含具有指定键的元素。

CopyTo(T[], Int32)

从目标数组的指定索引处开始将整个 Collection<T> 复制到兼容的一维 Array

(继承自 Collection<T>)
Equals(Object)

确定指定对象是否等于当前对象。

(继承自 Object)
GetEnumerator()

返回循环访问 Collection<T> 的枚举数。

(继承自 Collection<T>)
GetHashCode()

作为默认哈希函数。

(继承自 Object)
GetKeyForItem(TItem)

在派生类中实现时,将从指定元素提取键。

GetType()

获取当前实例的 Type

(继承自 Object)
IndexOf(T)

搜索指定的对象,并返回整个 Collection<T> 中第一个匹配项的从零开始的索引。

(继承自 Collection<T>)
Insert(Int32, T)

将元素插入 Collection<T> 的指定索引处。

(继承自 Collection<T>)
InsertItem(Int32, T)

将元素插入 Collection<T> 的指定索引处。

(继承自 Collection<T>)
InsertItem(Int32, TItem)

将元素插入 KeyedCollection<TKey,TItem> 的指定索引处。

MemberwiseClone()

创建当前 Object 的浅表副本。

(继承自 Object)
Remove(TKey)

KeyedCollection<TKey,TItem> 中移除包含指定键的元素。

RemoveAt(Int32)

移除 Collection<T> 的指定索引处的元素。

(继承自 Collection<T>)
RemoveItem(Int32)

移除 KeyedCollection<TKey,TItem> 的指定索引处的元素。

SetItem(Int32, T)

替换指定索引处的元素。

(继承自 Collection<T>)
SetItem(Int32, TItem)

使用指定项替换指定索引处的项。

ToString()

返回表示当前对象的字符串。

(继承自 Object)
TryGetValue(TKey, TItem)

尝试使用指定的键从集合中获取项。

显式接口实现

ICollection.CopyTo(Array, Int32)

从特定的 ICollection 索引开始,将 Array 的元素复制到一个 Array 中。

(继承自 Collection<T>)
ICollection.IsSynchronized

获取一个值,该值指示是否同步对 ICollection 的访问(线程安全)。

(继承自 Collection<T>)
ICollection.SyncRoot

获取可用于同步对 ICollection 的访问的对象。

(继承自 Collection<T>)
ICollection<T>.IsReadOnly

获取一个值,该值指示 ICollection<T> 是否为只读。

(继承自 Collection<T>)
IEnumerable.GetEnumerator()

返回循环访问集合的枚举数。

(继承自 Collection<T>)
IList.Add(Object)

将某项添加到 IList 中。

(继承自 Collection<T>)
IList.Contains(Object)

确定 IList 是否包含特定值。

(继承自 Collection<T>)
IList.IndexOf(Object)

确定 IList 中特定项的索引。

(继承自 Collection<T>)
IList.Insert(Int32, Object)

将某项插入 IList 中指定的索引处。

(继承自 Collection<T>)
IList.IsFixedSize

获取一个值,该值指示 IList 是否具有固定大小。

(继承自 Collection<T>)
IList.IsReadOnly

获取一个值,该值指示 IList 是否为只读。

(继承自 Collection<T>)
IList.Item[Int32]

获取或设置指定索引处的元素。

(继承自 Collection<T>)
IList.Remove(Object)

IList 中移除特定对象的第一个匹配项。

(继承自 Collection<T>)

扩展方法

ToFrozenDictionary<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IEqualityComparer<TKey>)

FrozenDictionary<TKey,TValue>根据指定的键选择器函数从 IEnumerable<T> 创建 。

ToFrozenDictionary<TSource,TKey,TElement>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TElement>, IEqualityComparer<TKey>)

根据指定的键选择器和元素选择器函数,从 IEnumerable<T> 创建一个 FrozenDictionary<TKey,TValue>

ToFrozenSet<T>(IEnumerable<T>, IEqualityComparer<T>)

FrozenSet<T>使用指定的值创建 。

AsReadOnly<T>(IList<T>)

返回指定列表的只读 ReadOnlyCollection<T> 包装器。

ToImmutableArray<TSource>(IEnumerable<TSource>)

从指定的集合创建一个不可变数组。

ToImmutableDictionary<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)

通过向源键应用转换函数,从现有元素集合构造一个不可变字典。

ToImmutableDictionary<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IEqualityComparer<TKey>)

基于对序列进行某种形式的转换来构造一个不可变字典。

ToImmutableDictionary<TSource,TKey,TValue>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TValue>)

枚举并转换序列,然后生成其内容的不可变字典。

ToImmutableDictionary<TSource,TKey,TValue>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TValue>, IEqualityComparer<TKey>)

枚举并转换序列,然后使用指定的键比较器生成其内容的不可变字典。

ToImmutableDictionary<TSource,TKey,TValue>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TValue>, IEqualityComparer<TKey>, IEqualityComparer<TValue>)

枚举并转换序列,然后使用指定的键和值比较器生成其内容的不可变字典。

ToImmutableHashSet<TSource>(IEnumerable<TSource>)

枚举序列,并生成其内容的不可变哈希集。

ToImmutableHashSet<TSource>(IEnumerable<TSource>, IEqualityComparer<TSource>)

枚举序列,生成其内容的不可变哈希集,并为集类型使用指定的相等性比较器。

ToImmutableList<TSource>(IEnumerable<TSource>)

枚举序列,并生成其内容的不可变列表。

ToImmutableSortedDictionary<TSource,TKey,TValue>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TValue>)

枚举并转换序列,然后生成其内容的不可变排序字典。

ToImmutableSortedDictionary<TSource,TKey,TValue>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TValue>, IComparer<TKey>)

枚举并转换序列,然后使用指定的键比较器生成其内容的不可变排序字典。

ToImmutableSortedDictionary<TSource,TKey,TValue>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TValue>, IComparer<TKey>, IEqualityComparer<TValue>)

枚举并转换序列,然后使用指定的键和值比较器生成其内容的不可变排序字典。

ToImmutableSortedSet<TSource>(IEnumerable<TSource>)

枚举序列,并生成其内容的不可变排序集。

ToImmutableSortedSet<TSource>(IEnumerable<TSource>, IComparer<TSource>)

枚举序列,生成其内容的不可变排序集,并使用指定的比较器。

CopyToDataTable<T>(IEnumerable<T>)

在给定其泛型参数 TDataTable 的输入 DataRow 对象的情况下,返回包含 IEnumerable<T> 对象副本的 DataRow

CopyToDataTable<T>(IEnumerable<T>, DataTable, LoadOption)

在给定其泛型参数 TDataRow 的输入 DataTable 对象的情况下,将 IEnumerable<T> 对象复制到指定的 DataRow

CopyToDataTable<T>(IEnumerable<T>, DataTable, LoadOption, FillErrorEventHandler)

在给定其泛型参数 TDataRow 的输入 DataTable 对象的情况下,将 IEnumerable<T> 对象复制到指定的 DataRow

Aggregate<TSource>(IEnumerable<TSource>, Func<TSource,TSource,TSource>)

对序列应用累加器函数。

Aggregate<TSource,TAccumulate>(IEnumerable<TSource>, TAccumulate, Func<TAccumulate,TSource,TAccumulate>)

对序列应用累加器函数。 将指定的种子值用作累加器初始值。

Aggregate<TSource,TAccumulate,TResult>(IEnumerable<TSource>, TAccumulate, Func<TAccumulate,TSource,TAccumulate>, Func<TAccumulate,TResult>)

对序列应用累加器函数。 将指定的种子值用作累加器的初始值,并使用指定的函数选择结果值。

AggregateBy<TSource,TKey,TAccumulate>(IEnumerable<TSource>, Func<TSource, TKey>, TAccumulate, Func<TAccumulate,TSource,TAccumulate>, IEqualityComparer<TKey>)

提供键嵌入在值中的集合的抽象基类。

AggregateBy<TSource,TKey,TAccumulate>(IEnumerable<TSource>, Func<TSource, TKey>, Func<TKey,TAccumulate>, Func<TAccumulate,TSource,TAccumulate>, IEqualityComparer<TKey>)

提供键嵌入在值中的集合的抽象基类。

All<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

确定序列中的所有元素是否都满足条件。

Any<TSource>(IEnumerable<TSource>)

确定序列是否包含任何元素。

Any<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

确定序列中是否存在任意一个元素满足条件。

Append<TSource>(IEnumerable<TSource>, TSource)

将一个值追加到序列末尾。

AsEnumerable<TSource>(IEnumerable<TSource>)

返回类型化为 IEnumerable<T> 的输入。

Average<TSource>(IEnumerable<TSource>, Func<TSource,Decimal>)

计算 Decimal 值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

Average<TSource>(IEnumerable<TSource>, Func<TSource,Double>)

计算 Double 值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

Average<TSource>(IEnumerable<TSource>, Func<TSource,Int32>)

计算 Int32 值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

Average<TSource>(IEnumerable<TSource>, Func<TSource,Int64>)

计算 Int64 值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

Average<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Decimal>>)

计算可以为 null 的 Decimal 值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

Average<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Double>>)

计算可以为 null 的 Double 值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

Average<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Int32>>)

计算可以为 null 的 Int32 值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

Average<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Int64>>)

计算可以为 null 的 Int64 值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

Average<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Single>>)

计算可以为 null 的 Single 值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

Average<TSource>(IEnumerable<TSource>, Func<TSource,Single>)

计算 Single 值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

Cast<TResult>(IEnumerable)

IEnumerable 的元素强制转换为指定的类型。

Chunk<TSource>(IEnumerable<TSource>, Int32)

将序列的元素拆分为最多 size大小的区块。

Concat<TSource>(IEnumerable<TSource>, IEnumerable<TSource>)

连接两个序列。

Contains<TSource>(IEnumerable<TSource>, TSource)

通过使用默认的相等比较器确定序列是否包含指定的元素。

Contains<TSource>(IEnumerable<TSource>, TSource, IEqualityComparer<TSource>)

通过使用指定的 IEqualityComparer<T> 确定序列是否包含指定的元素。

Count<TSource>(IEnumerable<TSource>)

返回序列中的元素数量。

Count<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

返回表示在指定的序列中满足条件的元素数量的数字。

CountBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IEqualityComparer<TKey>)

提供键嵌入在值中的集合的抽象基类。

DefaultIfEmpty<TSource>(IEnumerable<TSource>)

返回指定序列中的元素;如果序列为空,则返回单一实例集合中的类型参数的默认值。

DefaultIfEmpty<TSource>(IEnumerable<TSource>, TSource)

返回指定序列中的元素;如果序列为空,则返回单一实例集合中的指定值。

Distinct<TSource>(IEnumerable<TSource>)

通过使用默认的相等比较器对值进行比较,返回序列中的非重复元素。

Distinct<TSource>(IEnumerable<TSource>, IEqualityComparer<TSource>)

通过使用指定的 IEqualityComparer<T> 对值进行比较,返回序列中的非重复元素。

DistinctBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)

根据指定的键选择器函数从序列中返回不同的元素。

DistinctBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IEqualityComparer<TKey>)

根据指定的键选择器函数返回序列中的不同元素,并使用指定的比较器比较键。

ElementAt<TSource>(IEnumerable<TSource>, Index)

返回序列中指定索引处的元素。

ElementAt<TSource>(IEnumerable<TSource>, Int32)

返回序列中指定索引处的元素。

ElementAtOrDefault<TSource>(IEnumerable<TSource>, Index)

返回序列中指定索引处的元素;如果索引超出范围,则返回默认值。

ElementAtOrDefault<TSource>(IEnumerable<TSource>, Int32)

返回序列中指定索引处的元素;如果索引超出范围,则返回默认值。

Except<TSource>(IEnumerable<TSource>, IEnumerable<TSource>)

通过使用默认的相等比较器对值进行比较,生成两个序列的差集。

Except<TSource>(IEnumerable<TSource>, IEnumerable<TSource>, IEqualityComparer<TSource>)

通过使用指定的 IEqualityComparer<T> 对值进行比较,生成两个序列的差集。

ExceptBy<TSource,TKey>(IEnumerable<TSource>, IEnumerable<TKey>, Func<TSource,TKey>)

根据指定的键选择器函数生成两个序列的集差。

ExceptBy<TSource,TKey>(IEnumerable<TSource>, IEnumerable<TKey>, Func<TSource,TKey>, IEqualityComparer<TKey>)

根据指定的键选择器函数生成两个序列的集差。

First<TSource>(IEnumerable<TSource>)

返回序列中的第一个元素。

First<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

返回序列中满足指定条件的第一个元素。

FirstOrDefault<TSource>(IEnumerable<TSource>)

返回序列中的第一个元素;如果序列中不包含任何元素,则返回默认值。

FirstOrDefault<TSource>(IEnumerable<TSource>, TSource)

返回序列的第一个元素,如果序列不包含任何元素,则返回指定的默认值。

FirstOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

返回序列中满足条件的第一个元素;如果未找到这样的元素,则返回默认值。

FirstOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>, TSource)

返回序列中满足条件的第一个元素;如果未找到此类元素,则返回指定的默认值。

GroupBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)

根据指定的键选择器函数对序列中的元素进行分组。

GroupBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IEqualityComparer<TKey>)

根据指定的键选择器函数对序列中的元素进行分组,并使用指定的比较器对键进行比较。

GroupBy<TSource,TKey,TElement>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TElement>)

根据指定的键选择器函数对序列中的元素进行分组,并且通过使用指定的函数对每个组中的元素进行投影。

GroupBy<TSource,TKey,TElement>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TElement>, IEqualityComparer<TKey>)

根据键选择器函数对序列中的元素进行分组。 通过使用比较器对键进行比较,并且通过使用指定的函数对每个组的元素进行投影。

GroupBy<TSource,TKey,TResult>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TKey,IEnumerable<TSource>,TResult>)

根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值。

GroupBy<TSource,TKey,TResult>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TKey,IEnumerable<TSource>,TResult>, IEqualityComparer<TKey>)

根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值。 通过使用指定的比较器对键进行比较。

GroupBy<TSource,TKey,TElement,TResult>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TElement>, Func<TKey,IEnumerable<TElement>,TResult>)

根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值。 通过使用指定的函数对每个组的元素进行投影。

GroupBy<TSource,TKey,TElement,TResult>(IEnumerable<TSource>, Func<TSource, TKey>, Func<TSource,TElement>, Func<TKey,IEnumerable<TElement>, TResult>, IEqualityComparer<TKey>)

根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值。 通过使用指定的比较器对键值进行比较,并且通过使用指定的函数对每个组的元素进行投影。

GroupJoin<TOuter,TInner,TKey,TResult>(IEnumerable<TOuter>, IEnumerable<TInner>, Func<TOuter,TKey>, Func<TInner,TKey>, Func<TOuter,IEnumerable<TInner>, TResult>)

基于键值等同性对两个序列的元素进行关联,并对结果进行分组。 使用默认的相等比较器对键进行比较。

GroupJoin<TOuter,TInner,TKey,TResult>(IEnumerable<TOuter>, IEnumerable<TInner>, Func<TOuter,TKey>, Func<TInner,TKey>, Func<TOuter,IEnumerable<TInner>, TResult>, IEqualityComparer<TKey>)

基于键值等同性对两个序列的元素进行关联,并对结果进行分组。 使用指定的 IEqualityComparer<T> 对键进行比较。

Index<TSource>(IEnumerable<TSource>)

提供键嵌入在值中的集合的抽象基类。

Intersect<TSource>(IEnumerable<TSource>, IEnumerable<TSource>)

通过使用默认的相等比较器对值进行比较,生成两个序列的交集。

Intersect<TSource>(IEnumerable<TSource>, IEnumerable<TSource>, IEqualityComparer<TSource>)

通过使用指定的 IEqualityComparer<T> 对值进行比较,生成两个序列的交集。

IntersectBy<TSource,TKey>(IEnumerable<TSource>, IEnumerable<TKey>, Func<TSource,TKey>)

根据指定的键选择器函数生成两个序列的集交集。

IntersectBy<TSource,TKey>(IEnumerable<TSource>, IEnumerable<TKey>, Func<TSource,TKey>, IEqualityComparer<TKey>)

根据指定的键选择器函数生成两个序列的集交集。

Join<TOuter,TInner,TKey,TResult>(IEnumerable<TOuter>, IEnumerable<TInner>, Func<TOuter,TKey>, Func<TInner,TKey>, Func<TOuter,TInner,TResult>)

基于匹配键对两个序列的元素进行关联。 使用默认的相等比较器对键进行比较。

Join<TOuter,TInner,TKey,TResult>(IEnumerable<TOuter>, IEnumerable<TInner>, Func<TOuter,TKey>, Func<TInner,TKey>, Func<TOuter,TInner,TResult>, IEqualityComparer<TKey>)

基于匹配键对两个序列的元素进行关联。 使用指定的 IEqualityComparer<T> 对键进行比较。

Last<TSource>(IEnumerable<TSource>)

返回序列的最后一个元素。

Last<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

返回序列中满足指定条件的最后一个元素。

LastOrDefault<TSource>(IEnumerable<TSource>)

返回序列中的最后一个元素;如果序列中不包含任何元素,则返回默认值。

LastOrDefault<TSource>(IEnumerable<TSource>, TSource)

返回序列的最后一个元素,如果序列不包含任何元素,则返回指定的默认值。

LastOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

返回序列中满足条件的最后一个元素;如果未找到这样的元素,则返回默认值。

LastOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>, TSource)

返回序列中满足条件的最后一个元素;如果未找到此类元素,则返回指定的默认值。

LongCount<TSource>(IEnumerable<TSource>)

返回表示序列中元素总数的 Int64

LongCount<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

返回表示序列中满足条件的元素的数量的 Int64

Max<TSource>(IEnumerable<TSource>)

返回泛型序列中的最大值。

Max<TSource>(IEnumerable<TSource>, IComparer<TSource>)

返回泛型序列中的最大值。

Max<TSource>(IEnumerable<TSource>, Func<TSource,Decimal>)

对序列中的每个元素调用转换函数,并返回最大的 Decimal 值。

Max<TSource>(IEnumerable<TSource>, Func<TSource,Double>)

对序列中的每个元素调用转换函数,并返回最大的 Double 值。

Max<TSource>(IEnumerable<TSource>, Func<TSource,Int32>)

对序列中的每个元素调用转换函数,并返回最大的 Int32 值。

Max<TSource>(IEnumerable<TSource>, Func<TSource,Int64>)

对序列中的每个元素调用转换函数,并返回最大的 Int64 值。

Max<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Decimal>>)

对序列中的每个元素调用转换函数,并返回可以为 null 的最大的 Decimal 值。

Max<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Double>>)

对序列中的每个元素调用转换函数,并返回可以为 null 的最大的 Double 值。

Max<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Int32>>)

对序列中的每个元素调用转换函数,并返回可以为 null 的最大的 Int32 值。

Max<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Int64>>)

对序列中的每个元素调用转换函数,并返回可以为 null 的最大的 Int64 值。

Max<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Single>>)

对序列中的每个元素调用转换函数,并返回可以为 null 的最大的 Single 值。

Max<TSource>(IEnumerable<TSource>, Func<TSource,Single>)

对序列中的每个元素调用转换函数,并返回最大的 Single 值。

Max<TSource,TResult>(IEnumerable<TSource>, Func<TSource,TResult>)

对序列中的每个元素调用转换函数,并返回最大结果值。

MaxBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)

根据指定的键选择器函数返回泛型序列中的最大值。

MaxBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IComparer<TKey>)

根据指定的键选择器函数和键比较器返回泛型序列中的最大值。

Min<TSource>(IEnumerable<TSource>)

返回泛型序列中的最小值。

Min<TSource>(IEnumerable<TSource>, IComparer<TSource>)

返回泛型序列中的最小值。

Min<TSource>(IEnumerable<TSource>, Func<TSource,Decimal>)

对序列中的每个元素调用转换函数,并返回最小的 Decimal 值。

Min<TSource>(IEnumerable<TSource>, Func<TSource,Double>)

对序列中的每个元素调用转换函数,并返回最小的 Double 值。

Min<TSource>(IEnumerable<TSource>, Func<TSource,Int32>)

对序列中的每个元素调用转换函数,并返回最小的 Int32 值。

Min<TSource>(IEnumerable<TSource>, Func<TSource,Int64>)

对序列中的每个元素调用转换函数,并返回最小的 Int64 值。

Min<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Decimal>>)

对序列中的每个元素调用转换函数,并返回可以为 null 的最小的 Decimal 值。

Min<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Double>>)

对序列中的每个元素调用转换函数,并返回可以为 null 的最小的 Double 值。

Min<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Int32>>)

对序列中的每个元素调用转换函数,并返回可以为 null 的最小的 Int32 值。

Min<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Int64>>)

对序列中的每个元素调用转换函数,并返回可以为 null 的最小的 Int64 值。

Min<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Single>>)

对序列中的每个元素调用转换函数,并返回可以为 null 的最小的 Single 值。

Min<TSource>(IEnumerable<TSource>, Func<TSource,Single>)

对序列中的每个元素调用转换函数,并返回最小的 Single 值。

Min<TSource,TResult>(IEnumerable<TSource>, Func<TSource,TResult>)

对序列中的每个元素调用转换函数,并返回最小结果值。

MinBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)

根据指定的键选择器函数返回泛型序列中的最小值。

MinBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IComparer<TKey>)

根据指定的键选择器函数和键比较器返回泛型序列中的最小值。

OfType<TResult>(IEnumerable)

根据指定类型筛选 IEnumerable 的元素。

Order<T>(IEnumerable<T>)

按升序对序列的元素进行排序。

Order<T>(IEnumerable<T>, IComparer<T>)

按升序对序列的元素进行排序。

OrderBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)

根据键按升序对序列的元素进行排序。

OrderBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IComparer<TKey>)

使用指定的比较器按升序对序列的元素进行排序。

OrderByDescending<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)

根据键按降序对序列的元素进行排序。

OrderByDescending<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IComparer<TKey>)

使用指定的比较器按降序对序列的元素排序。

OrderDescending<T>(IEnumerable<T>)

按降序对序列的元素排序。

OrderDescending<T>(IEnumerable<T>, IComparer<T>)

按降序对序列的元素排序。

Prepend<TSource>(IEnumerable<TSource>, TSource)

向序列的开头添加值。

Reverse<TSource>(IEnumerable<TSource>)

反转序列中元素的顺序。

Select<TSource,TResult>(IEnumerable<TSource>, Func<TSource,TResult>)

将序列中的每个元素投影到新表单。

Select<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,TResult>)

通过合并元素的索引,将序列的每个元素投影到新窗体中。

SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>)

将序列的每个元素投影到 IEnumerable<T> 并将结果序列合并为一个序列。

SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>)

将序列的每个元素投影到 IEnumerable<T> 并将结果序列合并为一个序列。 每个源元素的索引用于该元素的投影表。

SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)

将序列的每个元素投影到 IEnumerable<T>,并将结果序列合并为一个序列,并对其中每个元素调用结果选择器函数。

SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)

将序列的每个元素投影到 IEnumerable<T>,并将结果序列合并为一个序列,并对其中每个元素调用结果选择器函数。 每个源元素的索引用于该元素的中间投影表。

SequenceEqual<TSource>(IEnumerable<TSource>, IEnumerable<TSource>)

通过使用相应类型的默认相等比较器对序列的元素进行比较,以确定两个序列是否相等。

SequenceEqual<TSource>(IEnumerable<TSource>, IEnumerable<TSource>, IEqualityComparer<TSource>)

通过使用指定的 IEqualityComparer<T> 来比较两个序列的元素,以确定这两个序列是否相等。

Single<TSource>(IEnumerable<TSource>)

返回序列的唯一元素;如果该序列并非恰好包含一个元素,则会引发异常。

Single<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

返回序列中满足指定条件的唯一元素;如果有多个这样的元素存在,则会引发异常。

SingleOrDefault<TSource>(IEnumerable<TSource>)

返回序列中的唯一元素;如果该序列为空,则返回默认值;如果该序列包含多个元素,此方法将引发异常。

SingleOrDefault<TSource>(IEnumerable<TSource>, TSource)

返回序列的唯一元素,如果序列为空,则返回指定的默认值;如果序列中有多个元素,此方法将引发异常。

SingleOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

返回序列中满足指定条件的唯一元素;如果这类元素不存在,则返回默认值;如果有多个元素满足该条件,此方法将引发异常。

SingleOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>, TSource)

返回序列中唯一满足指定条件的元素;如果不存在此类元素,则返回指定的默认值;如果多个元素满足条件,此方法将引发异常。

Skip<TSource>(IEnumerable<TSource>, Int32)

跳过序列中指定数量的元素,然后返回剩余的元素。

SkipLast<TSource>(IEnumerable<TSource>, Int32)

返回一个新的可枚举集合,它包含 source 中的元素,但省略了源集合中的 count 个元素。

SkipWhile<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

如果指定的条件为 true,则跳过序列中的元素,然后返回剩余的元素。

SkipWhile<TSource>(IEnumerable<TSource>, Func<TSource,Int32,Boolean>)

如果指定的条件为 true,则跳过序列中的元素,然后返回剩余的元素。 将在谓词函数的逻辑中使用元素的索引。

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Decimal>)

计算 Decimal 值序列的总和,这些值可通过对输入序列中的每个元素调用转换函数获得。

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Double>)

计算 Double 值序列的总和,这些值可通过对输入序列中的每个元素调用转换函数获得。

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Int32>)

计算 Int32 值序列的总和,这些值可通过对输入序列中的每个元素调用转换函数获得。

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Int64>)

计算 Int64 值序列的总和,这些值可通过对输入序列中的每个元素调用转换函数获得。

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Decimal>>)

计算可以为 null 的 Decimal 值序列的总和,这些值可通过对输入序列的每个元素调用转换函数获得。

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Double>>)

计算可以为 null 的 Double 值序列的总和,这些值可通过对输入序列的每个元素调用转换函数获得。

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Int32>>)

计算可以为 null 的 Int32 值序列的总和,这些值可通过对输入序列的每个元素调用转换函数获得。

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Int64>>)

计算可以为 null 的 Int64 值序列的总和,这些值可通过对输入序列的每个元素调用转换函数获得。

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Single>>)

计算可以为 null 的 Single 值序列的总和,这些值可通过对输入序列的每个元素调用转换函数获得。

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Single>)

计算 Single 值序列的总和,这些值可通过对输入序列中的每个元素调用转换函数获得。

Take<TSource>(IEnumerable<TSource>, Int32)

从序列的开头返回指定数量的相邻元素。

Take<TSource>(IEnumerable<TSource>, Range)

从序列中返回指定范围的连续元素。

TakeLast<TSource>(IEnumerable<TSource>, Int32)

返回一个新的可枚举集合,它包含 count 中的最后 source 个元素。

TakeWhile<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

只要指定的条件为 true,就会返回序列的元素。

TakeWhile<TSource>(IEnumerable<TSource>, Func<TSource,Int32,Boolean>)

只要指定的条件为 true,就会返回序列的元素。 将在谓词函数的逻辑中使用元素的索引。

ToArray<TSource>(IEnumerable<TSource>)

IEnumerable<T> 中创建数组。

ToDictionary<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)

根据指定的键选择器函数,从 IEnumerable<T> 创建一个 Dictionary<TKey,TValue>

ToDictionary<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IEqualityComparer<TKey>)

根据指定的键选择器函数和键比较器,从 IEnumerable<T> 创建一个 Dictionary<TKey,TValue>

ToDictionary<TSource,TKey,TElement>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TElement>)

根据指定的键选择器和元素选择器函数,从 IEnumerable<T> 创建一个 Dictionary<TKey,TValue>

ToDictionary<TSource,TKey,TElement>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TElement>, IEqualityComparer<TKey>)

根据指定的键选择器函数、比较器和元素选择器函数,从 IEnumerable<T> 创建一个 Dictionary<TKey,TValue>

ToHashSet<TSource>(IEnumerable<TSource>)

IEnumerable<T> 创建一个 HashSet<T>

ToHashSet<TSource>(IEnumerable<TSource>, IEqualityComparer<TSource>)

使用 comparer 通过 IEnumerable<T> 创建 HashSet<T>,以用于比较键。

ToList<TSource>(IEnumerable<TSource>)

IEnumerable<T> 创建一个 List<T>

ToLookup<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)

根据指定的键选择器函数,从 IEnumerable<T> 创建一个 Lookup<TKey,TElement>

ToLookup<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IEqualityComparer<TKey>)

根据指定的键选择器函数和键比较器,从 IEnumerable<T> 创建一个 Lookup<TKey,TElement>

ToLookup<TSource,TKey,TElement>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TElement>)

根据指定的键选择器和元素选择器函数,从 IEnumerable<T> 创建一个 Lookup<TKey,TElement>

ToLookup<TSource,TKey,TElement>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TElement>, IEqualityComparer<TKey>)

根据指定的键选择器函数、比较器和元素选择器函数,从 IEnumerable<T> 创建一个 Lookup<TKey,TElement>

TryGetNonEnumeratedCount<TSource>(IEnumerable<TSource>, Int32)

尝试在不强制枚举的情况下确定序列中的元素数。

Union<TSource>(IEnumerable<TSource>, IEnumerable<TSource>)

通过使用默认的相等比较器,生成两个序列的并集。

Union<TSource>(IEnumerable<TSource>, IEnumerable<TSource>, IEqualityComparer<TSource>)

通过使用指定的 IEqualityComparer<T> 生成两个序列的并集。

UnionBy<TSource,TKey>(IEnumerable<TSource>, IEnumerable<TSource>, Func<TSource,TKey>)

根据指定的键选择器函数生成两个序列的集联合。

UnionBy<TSource,TKey>(IEnumerable<TSource>, IEnumerable<TSource>, Func<TSource,TKey>, IEqualityComparer<TKey>)

根据指定的键选择器函数生成两个序列的集联合。

Where<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

基于谓词筛选值序列。

Where<TSource>(IEnumerable<TSource>, Func<TSource,Int32,Boolean>)

基于谓词筛选值序列。 将在谓词函数的逻辑中使用每个元素的索引。

Zip<TFirst,TSecond>(IEnumerable<TFirst>, IEnumerable<TSecond>)

使用两个指定序列中的元素生成元组序列。

Zip<TFirst,TSecond,TThird>(IEnumerable<TFirst>, IEnumerable<TSecond>, IEnumerable<TThird>)

使用三个指定序列中的元素生成元组序列。

Zip<TFirst,TSecond,TResult>(IEnumerable<TFirst>, IEnumerable<TSecond>, Func<TFirst,TSecond,TResult>)

将指定函数应用于两个序列的对应元素,以生成结果序列。

AsParallel(IEnumerable)

启用查询的并行化。

AsParallel<TSource>(IEnumerable<TSource>)

启用查询的并行化。

AsQueryable(IEnumerable)

IEnumerable 转换为 IQueryable

AsQueryable<TElement>(IEnumerable<TElement>)

将泛型 IEnumerable<T> 转换为泛型 IQueryable<T>

Ancestors<T>(IEnumerable<T>)

返回元素集合,其中包含源集合中每个节点的上级。

Ancestors<T>(IEnumerable<T>, XName)

返回经过筛选的元素集合,其中包含源集合中每个节点的上级。 集合中仅包括具有匹配 XName 的元素。

DescendantNodes<T>(IEnumerable<T>)

返回源集合中每个文档和元素的子代节点的集合。

Descendants<T>(IEnumerable<T>)

返回元素集合,其中包含源集合中每个元素和文档的子代元素。

Descendants<T>(IEnumerable<T>, XName)

返回经过筛选的元素集合,其中包含源集合中每个元素和文档的子代元素。 集合中仅包括具有匹配 XName 的元素。

Elements<T>(IEnumerable<T>)

返回源集合中每个元素和文档的子元素的集合。

Elements<T>(IEnumerable<T>, XName)

返回源集合中经过筛选的每个元素和文档的子元素集合。 集合中仅包括具有匹配 XName 的元素。

InDocumentOrder<T>(IEnumerable<T>)

返回节点集合(其中包含源集合中的所有节点),并按文档顺序排列。

Nodes<T>(IEnumerable<T>)

返回源集合中每个文档和元素的子节点集合。

Remove<T>(IEnumerable<T>)

将源集合中的每个节点从其父节点中移除。

适用于

另请参阅