Welcome to MSDN Blogs Sign in | Join | Help

SYSK 264: Restricting Item Types in Generic Collections

Say, you have implemented the following data class called Message in a YourCompany.DataContracts.Shared assembly (code below). 

When creating a collection of messages class, some may choose to implement it similar to the code below:

[DataContract(Namespace = ""), Serializable]

public class MessageCollection : System.Collections.Generic.SortedDictionary<DateTime, Message>

{

}

 

 

The problem with this approach is that if you created a class that derives from the Message class, let’s call it MessageEx, and you want a collection of the MessageEx classes, you’ll either have to create a new collection class (e.g. MessageExCollection), or you’ll end up writing a lot of code casting the collection items to the MessageEx type.

 

A better, in my opinion, choice is to create a generic collection, and restrict the type of items that are allowed to be inserted into such collection.  Here is what I mean:

 

#region MessageCollection

    [DataContract(Namespace = ""), Serializable]

    public class MessageCollection<T> : System.Collections.Generic.SortedDictionary<DateTime, T> where T : Message

    {

        public void Add(T item)

        {

            base.Add(item.CreatedOn, item);

        }

 

        public T this[long recordID]

        {

            get

            {

                T result = default(T);

 

                foreach (T item in base.Values)

                {

                    if (item.RecordID == recordID)

                    {

                        result = item;

                        break;

                    }

                }

 

                return result;

            }

        }

 

// TODO: add other methods/properties

//      (e.g. get by instance id, get by index, etc)

    }

#endregion

 

 

Now, you can have a Message class and MessageEx class, and instanced of both classes can be inserted into MessageCollection.  And yes, no casting required when inserting or retrieving and using the message item!

 

 

[DataContract(Namespace = ""), Serializable]

public class MessageEx : YourCompany.DataContracts.Shared.Message

{

    private string _someOtherData;

 

    [DataMember]

    public string SomeOtherData

    {

        get { return _someOtherData; }

        set { _someOtherData = value; }

    }   

}

 

 

namespace YourCompany.DataContracts.Shared

{

    #region Message

    [DataContract(Namespace = ""), Serializable]

    public class Message

    {

        private string _instanceID = Guid.NewGuid().ToString();

        private long _recordID;

        private string _text;

        private DateTime _createdOn;

        private string _createdBy;

 

        public Message()

        {

        }

 

        public Message(long recordId, string text, DateTime createdOn, string createdBy)

        {

            _recordID = recordId;

            _text = text;

            _createdOn = createdOn;

            _createdBy = createdBy;

        }

 

        [DataMember]

        public string InstanceID

        {

            get { return _instanceID; }

            set { _instanceID = value; }

        }

 

        [DataMember]

        public long RecordID

        {

            get { return _recordID; }

            set { _recordID = value; }

        }

 

        [DataMember]

        public string Text

        {

            get { return _text; }

            set { _text = value; }

        }

 

        [DataMember]

        public DateTime CreatedOn

        {

            get { return _createdOn; }

            set { _createdOn = value; }

        }

 

        [DataMember]

        public string CreatedBy

        {

            get { return _createdBy; }

            set { _createdBy = value; }

        }

    }

    #endregion

 

 

 

    [DataContract(Namespace = ""), Serializable]

    public class MessageEx : YourCompany.DataContracts.Shared.Message

    {

        private string _someOtherData;

 

        [DataMember]

        public string SomeOtherData

        {

            get { return _someOtherData; }

            set { _someOtherData = value; }

        }

    }

 

 

 

Usage:

 

MessageCollection<MessageEx> messages =

new MessageCollection<MessageEx>();

 

. . .


// No casting required :)

MessageEx message = messages[recordID];

 

 

Published Thursday, January 11, 2007 5:10 AM by irenak

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

No Comments

Leave a Comment

(required) 
required 
(required) 
 
Page view tracker