【问题标题】:How to create a custom collection in .NET 2.0如何在 .NET 2.0 中创建自定义集合
【发布时间】:2009-07-28 05:08:12
【问题描述】:

您好,我想创建我的自定义集合,我从 CollectionBase 类派生我的自定义集合类,如下所示:

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

class MyClass
{
    public string name;
}

让我问几个问题:

  1. 这种方法是否正确和新颖,因为我在 .NET 3.5 框架上工作。
  2. 我想从我的 Web 服务 (WCF) 中公开此集合。我该怎么做?
  3. 我必须实现 GetEnumerator 吗?
  4. 这是否会绑定到 DataGridView。

【问题讨论】:

  • 为什么你需要你的自定义收藏而不想使用现有的?
  • @Ashish:我格式化了您的帖子,请注意您应该在行首使用 4 个空格将其格式化为代码。
  • 由于我要验证集合的添加删除和删除操作。如果我创建自己的收藏,这将给我更多的控制权。
  • 您可能希望将标题更改为 3.5。

标签: c# wcf generics datagridview


【解决方案1】:

List<T> 派生有点毫无意义,尤其是现在它具有IEnumerable<T> 构造函数和扩展方法的可用性。除了EqualsGetHashCodeToString 之外,它没有可以覆盖的虚拟方法。 (如果您的目标是为列表实现 Java 的 toString() 功能,我想您可以从 List<T> 派生。)

如果您想创建自己的强类型集合类并可能在添加/删除项目时自定义集合行为,您希望从新的(到 .NET 2.0)类型System.Collections.ObjectModel.Collection<T> 派生,它具有受保护的虚拟包括InsertItemRemoveItem 在内的方法,您可以覆盖这些方法以在这些时间执行操作。请务必阅读文档 - 这是一个派生自非常容易的类,但您必须了解公共/非虚拟和受保护/虚拟方法之间的区别。 :)

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

【讨论】:

  • 超链接就在文本中,但我也会添加一个代码示例。
  • 只要您的对象明确定义为派生类,例如MyCollection collection = new MyCollection();,您就不需要虚拟方法。仅当您有 List&lt;MyClass&gt; collection = new MyCollection(); 时才需要它,在这种情况下这没有什么意义。我在这里使用继承来获得功能,而不是扩展类。尽管如此,关于Collection&lt;T&gt; 类的观点还是不错的。谢谢。
  • @Kobi:在非虚拟方法上使用 hide-by-name 肯定会导致维护噩梦。一旦有人以ICollection&lt;T&gt; 而不是MyCollection 对其进行操作,它就坏了。如果一个方法是非虚拟的,假设任何覆盖它的尝试都会出错。
  • 好点。我会记住那个的。你得到+1的解释。谢谢。
  • 感谢您的解释。你能告诉我从 List 派生我的收藏时我得到什么好处或坏处吗???
【解决方案2】:

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

  1. 当我在 .NET 3.5 框架上工作时,这种方法是否正确和新颖。
    • 没有。改用 List 或其他东西。
  2. 我想从我的 Web 服务 (WCF) 中公开这个集合。我该怎么做?
    • 通过。没用过 WCF。
  3. 我必须实现 GetEnumerator 吗?
    • 如果您使用标准 System.Collections.Generic 容器类之一,则不会。已经为您完成了
  4. 这是否会绑定到 DataGridView。
    • 任何支持 IEnumerable 的标准集合都可以很好地绑定到控件。如果您想要排序和过滤,可以考虑使用 IBindingListView。

【讨论】:

  • 根据我的经验,只要对象是可序列化的,您可能不会遇到 WCF 问题。扩展列表很好,只要内容也是可序列化的。请注意:像 Dictionary 这样的其他一些集合不可序列化 - 但仍然可以使用 List 实现您自己的可序列化“Dictionary”。
【解决方案3】:

如果你想要自己的集合类,你也可以从泛型集合继承到非泛型类,例如:

public class MyCollection : List<MyClass>
{

}

通过这种方式,您可以获得列表的所有功能(例如)。你只需要添加一些构造函数。

【讨论】:

    【解决方案4】:

    为什么不使用泛型集合?

    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,如果您想对添加和删除操作进行一些验证,您可以使用通用集合作为您的专业集合的成员:

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

    【讨论】:

    • 由于我要验证集合的添加删除和删除操作。如果我创建自己的收藏,这将给我更多的控制权。
    【解决方案5】:

    也许我在这里遗漏了一些东西,但是如果您只需要添加验证,为什么不从通用集合继承并覆盖 New() Remove() 或任何其他方法。

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

    【讨论】:

    • 感谢您的解释。你能告诉我从 System.Collections.ObjectModel.Collection 派生我的收藏时得到什么好处或坏处吗???
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    相关资源
    最近更新 更多