This documentation is archived and is not being maintained.

KeyedCollection<TKey, TItem>.Remove Method (TKey)

Removes the element with the specified key from the KeyedCollection<TKey, TItem>.

Namespace:  System.Collections.ObjectModel
Assembly:  mscorlib (in mscorlib.dll)

public bool Remove(
	TKey key


Type: TKey
The key of the element to remove.

Return Value

Type: System.Boolean
true if the element is successfully removed; otherwise, false. This method also returns false if key is not found in the KeyedCollection<TKey, TItem>.


key is null.

The key of the element is also removed from the lookup dictionary.

If the number of elements has exceeded the dictionary creation threshold and the KeyedCollection<TKey, TItem> is using a lookup dictionary, it will continue to use a lookup dictionary even though the number of elements is again under the threshold.


To customize the behavior of this method, override the RemoveItem method.

This method is an O(n) operation, where n is Count.

This code example shows the minimum code necessary to derive a collection class from KeyedCollection<TKey, TItem>: overriding the GetKeyForItem method and providing a public constructor that delegates to a base class constructor. The code example also demonstrates many of the properties and methods inherited from KeyedCollection<TKey, TItem> and Collection<T> classes.

The example demonstrates Remove method inherited from KeyedCollection<TKey, TItem>, which removes the item with a specified key, and also the Remove and RemoveAt methods inherited from Collection<T>, which remove by object and by index respectively.

The SimpleOrder class is a very simple requisition list that contains OrderItem objects, each of which represents a line item in the order. The key of OrderItem is immutable, an important consideration for classes that derive from KeyedCollection<TKey, TItem>. For a code example that uses mutable keys, see ChangeItemKey.

using 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>
    // 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() : base() {}

    // 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));


        // The Contains method of KeyedCollection takes the key, 
        // type, in this case int.
        Console.WriteLine("\nContains(101030411): {0}", 

        // The default Item property of KeyedCollection takes a key.
        Console.WriteLine("\nweekly[101030411].Description: {0}", 

        // The Remove method of KeyedCollection takes a key.

        // 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}", 

        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.



    private static void Display(SimpleOrder order)
        foreach( OrderItem item in order )

// 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; }
            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


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


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


110072675     27 Sprocket     at     5.30 =     143.10
110072684    175 Gear         at     5.17 =     904.75

.NET Framework

Supported in: 4, 3.5, 3.0, 2.0

.NET Framework Client Profile

Supported in: 4, 3.5 SP1

Portable Class Library

Supported in: Portable Class Library

Windows 7, Windows Vista SP1 or later, Windows XP SP3, Windows XP SP2 x64 Edition, Windows Server 2008 (Server Core not supported), Windows Server 2008 R2 (Server Core supported with SP1 or later), Windows Server 2003 SP2

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.