Why and when to inherit from Collection

后端 未结 4 884
我寻月下人不归
我寻月下人不归 2021-01-17 21:08

I\'m tracing legacy code in my project written in C#.

I find the following code:

public class FooCollection : Collection {};
相关标签:
4条回答
  • 2021-01-17 21:22

    I don't understand why (and when) we need to create our own Collection class like this.

    One of the main use cases for implementing a custom Collection<T> is serialization.

    If you want to customize how the collection is serialized (for example to XML, using XmlSerializable), you can create a custom collection class and implement IXmlSerializable on it. Then, you can change how to read or write the collection by manipulating the Read and Write methods of that interface.

    class MyCollection : Collection<string>, IXmlSerializable
    {
        public XmlSchema GetSchema()
        {
            return(null);
        }
    
        public void WriteXml(XmlWriter writer)
        {
            //// foreach (var item in Items)
                //// writer.Write...
        }
    
        public void ReadXml(XmlReader reader)
        {
            //// Items.Add(reader.Read...
        }
    }
    

    This is in most cases preferable compared to implementing IXmlSerializable on the parent class, as it leads to less code overall and promotes reuse (you can reuse the same collection in multiple places and it will be serialized in the same way as long as you use a XmlSerializer to serialize it).

    I've used this recently due to a requirement from an external system that needed each element of the collection to generate a XML node with the index of the element appended to it.

    The final structure looked somewhat like this:

    <MyCollection>
      <Item1>first item</Item1>
      <Item2>second item</Item2>
      ...
    </MyCollection>
    

    I'm not fond of coupling the collection to the serialization like this, but sometimes it is a valid approach.

    0 讨论(0)
  • 2021-01-17 21:33

    I don't understand why (and when) we need to create our own Collection class like this.

    I never would. I personally find the Collection class to not be useful at all. I have not yet found a use for it.

    One of the main problems with the type is that most of the method aren't virtual. The only virtual methods that are ClearItems, InsertItem, RemoveItem, and SetItem (along with Equals, GetHashCode, and ToString from Object). The rest of the methods/properties aren't virtual, and so cannot be overridden. This means you can alter the semantics for adding/inserting/removing an item slightly, but that's all.

    What's the data structure used in Collection<T>?

    Internally it is backed by a List<T>.

    Why not just use the build-in collection (array, List<T>, Dictionary<K,V>, ...)

    In virtually all instances you would. While there are occasional instances in which you might actually want to create a brand new collection type, I've never found a use in which Collection<T> was helpful in creating such a custom collection. Generally it's just best to implement some of the interfaces in the Collections namespace, based on what your collection can fulfill, and optionally compose the type using other collections as instance fields, if it is merely an extension of an existing collection.

    0 讨论(0)
  • 2021-01-17 21:35

    I don't understand why (and when) we need to create our own Collection class like this.

    You don't really "need" to; you could just use Collection<IFoo> directly, but having a specific class can help readability.

    Also, it allows you to add specific behavior for this collection type as the Collection<T> class allows most operations to be redefined by overriding virtual methods; this allows you to customize the behavior of the standard collection methods.

    So, for example, while you cannot directly override the Add method, you can override InsertItem which is then used by Add, AddRange etc.

    Why not just use the build-in collection (array, List, Dictionary, ...)

    An array has a fixed length, so you can't add or remove items; so it's not really equivalent. Dictionary<K,V> associates a value with a key, so it has a clearly different purpose. List<T> could be used instead, as long as you don't need to customize the behavior; this class is not designed for inheritance, since its methods are non-virtual.

    What's the data structure used in Collection ?? array? or linked list?

    Collection<T> acts as a wrapper around another IList<T>. By default, it uses a List<T> (which is based on an array), but you can pass any other IList<T> implementation to the constructor, and it will use that instead.

    0 讨论(0)
  • 2021-01-17 21:41

    By stating that you are inheriting the Collection<T> class, you declare that your class IS-A Collection<T>, meaning that you have all it's API implemented (either by the derived class or by base the Collection<T> class).

    The advantage in the inheritance is that you can decide to override some of the methods and handle them in a way you find more suitable to your needs or to the type T (IFoo in your case).

    In the same manner you can also decide to extend your API in order to support some other functionality that you find appropriate for your situation.

    For example if you class IFoo looks some thing like this:

    public interface IFoo
    {
       int a;
       int b;
    }
    

    In your derived class you can add an overload to the Remove that will look something like:

    public bool Remove(int a, int b )...
    

    And it will remove all occurrences of items that has certain values for a and b

    0 讨论(0)
提交回复
热议问题