Click here to Skip to main content
6,629,377 members and growing! (22,777 online)
Email Password   helpLost your password?
General Programming » Collections » General     Intermediate License: The Common Development and Distribution License (CDDL)

KeyedList, Extending the KeyedCollection

By Rune Baess

An attempt to offer an alternative to the generic KeyedCollection.
C# (C# 1.0, C# 2.0, C# 3.0), .NET (.NET 2.0, .NET 3.0, .NET 3.5), Dev
Posted:25 Sep 2008
Views:7,799
Bookmarked:23 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
5 votes for this article.
Popularity: 2.87 Rating: 4.11 out of 5
1 vote, 20.0%
1

2

3
2 votes, 40.0%
4
2 votes, 40.0%
5

Introduction

This an attempt to offer an alternative to the generic KeyedCollection for ease of use.

Background

I'm a fan of the KeyedCollection. Simply because, in a simple way, it resembles how a table in a database works. The objects in the KeyedCollection contain their key values. This makes it a good candidate for caching and handling business data in memory in a database-like manner.

However, a few thing are annoying when dealing with the KeyedCollection:

  • It's abstract, so you'll have to make an implementation to use it.
  • Unlike tables from a database, you can use only one value as your key.

The primary objective

The primary objective of the KeyedList project is to make a more easy-to-use version of the Generic KeyedCollection, that can be used like this:

KeyedList<string, MyClass> list = new KeyedList<string, MyClass>();
if(list.Contains("key"))
{
    MyClass item = list["key"];
}

Using the code

The KeyedCollection is abstract, and requires an implementation to work; more specifically, you'll have to implement a method GetKeyForItem() that will provide a key for the KeyedCollection for the items in the list.

The KeyedList is, in fact, an implementation of the KeyedCollection, but it offers three alternate ways to let the user provide keys for the chosen item.

  1. By passing in a delegate on instantiation:
  2. KeyedList<string, MyClass> list = 
       new KeyedList<string, MyClass>(x => x.KeyValue);
    
    // or if you don't like the lampda
    KeyedList<string, MyClass> list = 
       new KeyedList<string, MyClass>( delegate(MyClass x){ return x.Keyvalue; } );
  3. Implementing an interface on the target class:
  4. class MyClass : IKeyedItem<string>  
    {
        string IKeyedItem<string>.Key     
        {        
            get { return this.KeyValue; }  
                }  
    }
    
    KeyedList<string, MyClass> list = new KeyedList<string, MyClass>(); 
    // etc..
  5. Or finally, by decorating the "Key" property with a DataObjectField attribute:
  6. class MyClass : IKeyedItem<string>  
    {      
        [DataObjectField(true)]      
        public string KeyValue { get; set; }  
    }  
    
    KeyedList<string, MyClass> list = new KeyedList<string, MyClass>();  
    // etc..

When the key is a combination of values

Then what? Today's Dictionarys and KeyedCollections do not offer a straightforward solution. Let's imagine we have a table that holds order lines... the key would usually be a combination of an OrderId and a LineNumber. The key is only unique when you combine these values. How do you represent that structure using a Dictionary to enforce the uniqueness?

// I was goingfor something like this:

KeyedList<int, string, MyClass> list = new KeyedList<int, string, MyClass>();
if(list.Contains(2, "key"))
{
    MyClass item = list[2,"key"];
}
//  etc ...

I have a suggestion on how to resolve this issue. By using a lightweight generic structure to hold the values as if they were one, and at the same time, providing its own comparer for the Dictionary.

public struct Key<T1, T2> : IEquatable<Key<T1, T2>>
{
      public Key(T1 value1, T2 value2)
    {
               // ...
    }
}

class KeyEqualityComparer<T1, T2> : EqualityComparer<Key<T1, T2>>
{
    // ...
}

You can actually use it directly with a normal Dictionary, like this:

Dictionary<Key<int, int>, MyClass> dictionary = 
  new Dictionary<Key<int, int>, MyClass>(Key<int, int>.Comparer);
// etc..
    
MyClass item = dictionary[new Key(123, 456)];

However, I find it more elegant and easy to use to have it embedded directly in the KeyedList itself.

If you have inputs or feel like adding, correcting, or improve the code, please join the project at Codeplex.

Points of interest

I find that caching more and more data in a more and more complex form seems to be a trend. For that reason, I applaud whenever new and interesting methods and technologies that make this easier comes along... first, the anonymous methods, and later, Lambda expressions and LINQ for Objects. However, I always prefer simple objects over ADO DataSets and DataTables to hold my data in memory; they are simply too heavy and too slow if your data reaches certain amounts. So, out of necessity, I made this implementation.

History

None so far.

License

This article, along with any associated source code and files, is licensed under The Common Development and Distribution License (CDDL)

About the Author

Rune Baess


Member
Software designer/developer with specialization in distributed applications, E-commerce and MS Dynamics Integration using Microsoft .NET Technologies.

Software Design and Development since 1999.
.NET since 2001
Occupation: Software Developer (Senior)
Company: Enyosoft
Location: Denmark Denmark

Other popular Collections articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 4 of 4 (Total in Forum: 4) (Refresh)FirstPrevNext
GeneralMultiple keys PinmemberPaul B.8:52 29 Sep '08  
GeneralRe: Multiple keys PinmemberRune Baess10:33 29 Sep '08  
GeneralRe: Multiple keys PinmemberRune Baess10:51 29 Sep '08  
GeneralRe: Multiple keys PinmemberPaul B.4:55 30 Sep '08  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 25 Sep 2008
Editor: Smitha Vijayan
Copyright 2008 by Rune Baess
Everything else Copyright © CodeProject, 1999-2009
Web22 | Advertise on the Code Project