KeyedCollection<TKey,TItem>.GetKeyForItem(TItem) 方法

定义

在派生类中实现时,将从指定元素提取键。When implemented in a derived class, extracts the key from the specified element.

protected:
 abstract TKey GetKeyForItem(TItem item);
protected abstract TKey GetKeyForItem (TItem item);
abstract member GetKeyForItem : 'Item -> 'Key
Protected MustOverride Function GetKeyForItem (item As TItem) As TKey

参数

item
TItem

从中提取键的元素。The element from which to extract the key.

返回

TKey

指定元素的键。The key for the specified element.

示例

此代码示例演示从派生集合类所需的最少代码 KeyedCollection<TKey,TItem> :重写 GetKeyForItem 方法,并提供委托给基类构造函数的公共构造函数。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. 此代码示例还演示了继承自和类的多个属性和方法 KeyedCollection<TKey,TItem> Collection<T>The code example also demonstrates many of the properties and methods inherited from KeyedCollection<TKey,TItem> and Collection<T> classes.

SimpleOrder类是一个非常简单的请求列表,其中 OrderItem 每个对象都表示顺序中的行项。The SimpleOrder class is a very simple requisition list that contains OrderItem objects, each of which represents a line item in the order. 的键 OrderItem 是不可变的,它是派生自的类的重要注意事项 KeyedCollection<TKey,TItem>The key of OrderItem is immutable, an important consideration for classes that derive from KeyedCollection<TKey,TItem>. 有关使用可变键的代码示例,请参见 ChangeItemKeyFor 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

注解

如果查找字典中的键不同于中嵌入的键 item ,则不能 item 使用返回的键访问 GetKeyForItemIf the key in the lookup dictionary is different from the key that is embedded in item, you cannot access item by using the key returned by GetKeyForItem.

您可以实现此方法以便 null 为包含没有键的项的集合返回,在这种情况下,只能通过索引来访问项。You can implement this method to return null for a collection that contains items without keys, in which case the items can be accessed only by their index. 此方法是 O (1) 操作。This method is an O(1) operation.

实施者注意事项Notes for Implementers

必须重写此方法以提供一种方法,以便从字典中的项中提取键。You must override this method to provide the dictionary with a way to extract keys from items in the dictionary.

此方法在内部调用。This method is called internally. 它不是公共的。It is not necessary for it to be public.

适用于

另请参阅