Custom KeyCollection

  • Thread starter Thread starter JoSkillz
  • Start date Start date
J

JoSkillz

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?
}
}
 
IMHO you have 2 options:

return the key that satisfies the value ( find value in the list that is
equal to item and another may be auto-key generation for example

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

You can return either incremented value, hashcode, or some calculated value
 
You need to return the unique key:

public class PersonCollection : KeyedCollection<int, Person>
{
public PersonCollection() : base() { }

protected override int GetKeyForItem(Person person)
{
return person.ID;
}
}

PersonCollection pc = new PersonCollection();
pc.Add(new Person(1, "Gabriel", "Lozano-Morán");

Gabriel Lozano-Morán
MCSD .NET
Real Software
http://www.realdn.net
http://www.realsoftware.be
 
You 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 and rely on the power of Generics to work for me.
 
One way to solve this is to make sure that the generic part, like Chapter or
Person implement an interface for example:

public interface IKeyed
{
int Key { get; }
}

Then add the generic constraint where T is IKeyed and in the GetKeyForItem()
return the Key property.

Gabriel
 
How do I add a constraint to the generic to be a certain type? because
in that case I can declare the type to always be of type DomainBase.
 
Eg:

public class GenericKeyedCollection<Key, Type> : KeyedCollection<Key, Type>
where Type : IKeyed

Gabriel
 
Just when I just starting to wrap my hands around HQL and Generics they
do this! Geesh.. I need to upgrade my brain it's becoming outdated.
 
I know it's hard to keep up. And then if you see what profiles employers
require, it's becoming impossible. I used to be a contractor but it was
really hard to get projects because being a contractor they expected from
you that you know everything.

Gabriel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top