5

Hi I want to create my custom collection, I am deriving my custom collection class from CollectionBase class as below:

public class MyCollection : System.Collections.CollectionBase
{
    MyCollection(){}
    public void Add(MyClass item)
    {
        this.List.Add(item);
    }
}

class MyClass
{
    public string name;
}

Let me ask a few questions:

  1. Whether this approach is correct and new, as I working on .NET 3.5 framework.
  2. I want to expose this collection from my web service ( WCF) .How can I do that?
  3. Do I have to implement GetEnumerator?
  4. Whether this will Bind to DataGridView.
4
  • 1
    why you need your custom collection and don't want to use existing ones? Commented Jul 28, 2009 at 5:16
  • @Ashish: I formatted your post, note that you should use 4 spaces at the beginning of a line to get it formatted as code. Commented Jul 28, 2009 at 5:22
  • Since I want to validate the add remove and delete operation of the collection. This will give me more control if i create my own collection. Commented Jul 28, 2009 at 5:24
  • 1
    You probably want to change the title to 3.5. Commented Jul 28, 2009 at 5:33

5 Answers 5

8

Deriving from List<T> is somewhat pointless, especially now that it has the IEnumerable<T> constructor and the availability of extension methods. It has no virtual methods that you can override except Equals, GetHashCode, and ToString. (I suppose you could derive from List<T> if your goal was to implement Java's toString() functionality for lists.)

If you want to create your own strongly-typed collection class and possibly customize the collection behavior when items are add/removed, you want to derive from the new (to .NET 2.0) type System.Collections.ObjectModel.Collection<T>, which has protected virtual methods including InsertItem and RemoveItem that you can override to perform actions at those times. Be sure to read the documentation - this is a very easy class to derive from but you have to realize the difference between the public/non-virtual and protected/virtual methods. :)

public class MyCollection : Collection<int>
{
    public MyCollection()
    {
    }

    public MyCollection(IList<int> list)
        : base(list)
    {
    }

    protected override void ClearItems()
    {
        // TODO: validate here if necessary
        bool canClearItems = ...;
        if (!canClearItems)
            throw new InvalidOperationException("The collection cannot be cleared while _____.");

        base.ClearItems();
    }

    protected override void RemoveItem(int index)
    {
        // TODO: validate here if necessary
        bool canRemoveItem = ...;
        if (!canRemoveItem)
            throw new InvalidOperationException("The item cannot be removed while _____.");

        base.RemoveItem(index);
    }
}
Sign up to request clarification or add additional context in comments.

7 Comments

The hyperlink is right there in the text, but I'll add a code sample too.
As long as your objects are defined explicitly as the deriving class, eg, MyCollection collection = new MyCollection();, you don't need the methods to be virtual. You only need it if you have List<MyClass> collection = new MyCollection();, and that makes little sense in this case. I'm using inheritance here to get functionality, not to expand a class. Still, good point about the Collection<T> class. Thanks.
@Kobi: Using hide-by-name on non-virtual methods is a guaranteed way to cause a maintenance nightmare. As soon as someone operates on it as an ICollection<T> instead of MyCollection, it's broken. If a method is non-virtual, assume that any attempt to override it will go horribly wrong.
Good point. I'll remember that one. You get +1 for the explanation. Thanks.
Thanks for the explanation. Can you please give me what is advantange or disadvantage i get when deriving my collection from List<T>???
|
5

I think you would be better off using one of the container classes defined in System.Collections.Generic

  1. Whether this approach is correct and new, as I working on .NET 3.5 framework.
    • No. Use List or something instead.
  2. I want to expose this collection from my web service ( WCF) .How can I do that?
    • pass. haven't used WCF.
  3. Do I have to implement GetEnumerator?
    • not if you use one of the standard System.Collections.Generic container classes. It's already done for you
  4. Whether this will Bind to DataGridView.
    • Any of the standard collections that support IEnumerable will bind to controls pretty well. You could look at using IBindingListView if you want sorting and filtering.

1 Comment

In my experience, as long as the object is serializable, you probably won't encounter problems with WCF. Extending List is a good, as long as the contents are serializable too. Just note: Some other collections like Dictionary aren't serializable - but it's still possible to implement your own serializable "Dictionary" using a List.
3

If you want your own collection class you can also inherit from a generic collection to a non-generic class, eg:

public class MyCollection : List<MyClass>
{

}

This way you get all the functionality of a list (for example). You just need to add a few constructors.

Comments

1

Why not using a generic collection?

using System;
using System.Collections.Generic;

namespace Test {
    class MyClass { 
    }
    class Program {
        static void Main(string[] args) {
            // this is a specialized collection
            List<MyClass> list = new List<MyClass>();
            // add elements of type 'MyClass'
            list.Add(new MyClass());
            // iterate
            foreach (MyClass m in list) { 
            }
        }
    }
}

EDIT: Ashu, if you want to do some validation on Add and Remove operations you could use a generic collection as member of your specialized collection:

using System;
using System.Collections.Generic;
namespace Test {
    class MyClass { 
    }
    class MyClassList {
        protected List<MyClass> _list = new List<MyClass>();
        public void Add(MyClass m) { 
            // your validation here...
            _list.Add(m);
        }
        public void Remove(MyClass m) {
            // your validation here...
            _list.Remove(m);
        }
        public IEnumerator<MyClass> GetEnumerator() {
            return _list.GetEnumerator();
        }
    }
    class Program {
        static void Main(string[] args) {
            MyClassList l = new MyClassList();
            l.Add(new MyClass());
            // iterate
            foreach (MyClass m in l) { 
            }
        }
    }
}

1 Comment

Since I want to validate the add remove and delete operation of the collection. This will give me more control if i create my own collection.
0

Maybe I'm missing something here, but if you just need to add validations why don't you inherit from a generic collection and override the New() Remove() or any other method.

class CustomeCollection<T> : List<T>
{
    public new void Add(T item)
    {
        //Validate Here
        base.Add(item);
    }

    public new void Remove(T item)
    {
        //Validate Here
        base.Remove(item);
    }

}

1 Comment

Thanks for the explanation. Can you please give me what is advantange or disadvantage i get when deriving my collection from System.Collections.ObjectModel.Collection<T>???

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.