For Programmers: Free Programming Magazines  


Home > Archive > C# > December 2005 > Create a Custom Generic Keyed Collection









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Create a Custom Generic Keyed Collection
JoSkillz

2005-12-12, 10:10 pm

I am trying to create a custom KeyCollection that will only allow my
domain objects to be added to the Collection. I was hoping I could
achieve the following implementation.

GenericKeyedCollection<int, Person> collection = new
GenericKeyedCollection<int, Person>();

Person person1 = new Person();
person1.ID = 1;
person1.Name = "Jimmy";

Person person2 = new Person();
person2.ID = 2;
person2.Name = "Chris";

collection.Add(person1);
collection.Add(person2);

Assert.AreEqual(2, collection.Count);

Now I thought I understood how to do this but I don't know what to
put in the absratct protected override GetKeyForItem. Can someone
please give me some guidance on what to put here?


Here is my implmentation of the GenericKeyedCollection.

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;

namespace Unity.Domain
{
public class GenericKeyedCollection<Key, Type> : KeyedCollection<Key,
Type>
{
protected override Key GetKeyForItem(Type item)
{
//What do I put here since at runtime
//I don't know what the
type will be?
}
}
}

Bruce Wood

2005-12-12, 10:10 pm

Take this with a grain of salt, because I'm still using 1.1, but...

It appears to me that you have two choices. First possibility:

public class PersonCollection : KeyedCollection<string, Person>
{
protected override string GetKeyForItem(Person item)
{
... now you know that it's a Person object ...
}
}

Or, the second possibility, create an interface, say IKeyed, and insist
that all of your domain objects implement it:

public interface IKeyed
{
string PrimaryKey { get; }
}

public class GenericKeyedCollection<Type : IKeyed> :
KeyedCollection<string, Type>
{
protected override string GetKeyForItem(Type item)
{
IKeyed keyedItem = (IKeyed)item;
return keyedItem.PrimaryKey;
}
}

.... or something like that.

JoSkillz

2005-12-12, 10:10 pm

Thanks for the reply Bruce,

You second suggestion would work however I would lose the generic
instantiation of the "GenericKeyedCollection" class from a generics
perspective. I want to be able to declare the following private field
declarations.

public class Chapter : DomainBase {}

public class Book : DomainBase
{
private GenericKeyedCollection<int, Chapter> chapters = new
GenericKeyedCollection<int, Chapter>();
}

public class Shelf : DomainBase
{
//Use string as key becuase we will be using the ISBN
private GenericKeyedCollection<string, Book> books = new
GenericKeyedCollection<string, Book>();
}

That way I would be able to use the GenericKeyCollection with ANY
object in the future.

Bruce Wood

2005-12-12, 10:10 pm

As I said, I'm not using generics yet, so I don't know if you can do
things like this:

public interface IKeyed<KeyType>
{
public KeyType PrimaryKey { get; }
}

public class GenericKeyedCollection<Key, Type : IKeyed<Key>> :
KeyedCollection<Key, Type>
{
protected override string GetKeyForItem(Type item)
{
IKeyed<Key> keyedItem = (IKeyed<Key> )item;
return keyedItem.PrimaryKey;
}
}

Can generics handle that sort of monkey business? :-)

JoSkillz

2005-12-12, 10:10 pm

Not sure??? New to 2.0 as well. We need to find the monkey and ask
him. :-)

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com