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. :-)
|
|
|
|
|