关于C#:如何在.NET 2.0中创建自定义集合

How to create a custom collection in .NET 2.0

嗨,我想创建自定义集合,我正在从CollectionBase类派生自定义集合类,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class MyCollection : System.Collectio.CollectionBase
{
    MyCollection(){}
    public void Add(MyClass item)
    {
        this.List.Add(item);
    }
}

class MyClass
{
    public string name;
}

让我问几个问题:

  • 正如我在处理.NET 3.5框架时所做的那样,这种方法是否正确、新。
  • 我想从我的Web服务(WCF)公开此集合。我如何才能这样做?
  • 我必须实现getEnumerator吗?
  • 是否绑定到DataGridView。

  • List派生是没有意义的,特别是现在它有了IEnumerable构造函数和扩展方法的可用性。除了EqualsGetHashCodeToString之外,它没有可以重写的虚拟方法。(假设您的目标是实现Java的ToStRun()列表功能,那么您可以从EDCOX1 0派生。

    如果要创建自己的强类型集合类,并可能在添加/删除项时自定义集合行为,则需要从新的(to.NET 2.0)类型System.Collections.ObjectModel.Collection派生,该类型具有保护虚拟方法,包括InsertItemRemoveItem,您可以重写这些方法以在此时执行操作。请务必阅读文档-这是一个非常容易派生的类,但是您必须认识到公共/非虚拟和受保护/虚拟方法之间的区别。:)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    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);
        }
    }


    我认为最好使用System.Collections.Generic中定义的容器类之一。

  • 正如我在处理.NET 3.5框架时所做的那样,这种方法是否正确、新。
    • 不,用列表或其他东西代替。
  • 我想从我的Web服务(WCF)公开此集合。我如何才能这样做?
    • 通过。尚未使用WCF。
  • 我必须实现getEnumerator吗?
    • 如果使用标准System.Collections.Generic容器类之一,则不会。已经为你做了
  • 是否绑定到DataGridView。
    • 任何支持IEnumerable的标准集合都将很好地绑定到控件。如果需要排序和筛选,可以使用IBindingListView。

  • 如果需要自己的集合类,还可以从泛型集合继承到非泛型类,例如:

    1
    2
    3
    4
    public class MyCollection : List<MyClass>
    {

    }

    这样就可以获得列表的所有功能(例如)。您只需要添加一些构造函数。


    为什么不使用通用集合?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    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) {
                }
            }
        }
    }

    编辑:ashu,如果要对添加和删除操作进行一些验证,可以将通用集合用作专用集合的成员:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    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) {
                }
            }
        }
    }


    也许我这里遗漏了一些东西,但是如果您只需要添加验证,那么为什么不从泛型集合继承并重写New()Remove()或任何其他方法呢?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    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);
        }

    }