views:

640

answers:

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.Collectio.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.
+3  A: 

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.
Hamish Smith
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.
Loki
+1  A: 

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) { 
            }
        }
    }
}
Paolo Tedesco
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.
Ashish Ashu
+3  A: 

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.

Kobi
+5  A: 

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);
    }
}
280Z28
Can you please give me some starting point or Link
Ashish Ashu
The hyperlink is right there in the text, but I'll add a code sample too.
280Z28
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
@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.
280Z28
Good point. I'll remember that one. You get +1 for the explanation. Thanks.
Kobi
Thanks for the explanation. Can you please give me what is advantange or disadvantage i get when deriving my collection from List<T>???
Ashish Ashu
@Ashish: What? That's the sole content of my answer...?
280Z28
Note that Collection<T> doesn't support sorting, but the Sort() method can be implemented with a few lines of code: http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/977ac532-afc9-46b7-bd73-a5cc41086b9c/
salle55
A: 

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);
    }

}
Keivan
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>???
Ashish Ashu