Как создать собственную коллекцию в .NET 2.0

Здравствуйте, я хочу создать свою собственную коллекцию, я получаю свой собственный класс коллекции из класса CollectionBase, как показано ниже:

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

class MyClass
{
    public string name;
}

Позвольте мне задать несколько вопросов:

Whether this approach is correct and new, as I working on .NET 3.5 framework. I want to expose this collection from my web service ( WCF) .How can I do that? Do I have to implement GetEnumerator? Whether this will Bind to DataGridView.
 Kobi28 июл. 2009 г., 07:33
Вы, вероятно, хотите изменить название на 3,5.
 Ashish Ashu28 июл. 2009 г., 07:24
Так как я хочу проверить операцию удаления и удаления из коллекции. Это даст мне больше контроля, если я создам свою собственную коллекцию.
 Paolo Tedesco28 июл. 2009 г., 07:22
@Ashish: я отформатировал ваш пост, обратите внимание, что вы должны использовать4 пробелы в начале строки для ее форматирования в виде кода.
 Arsen Mkrtchyan28 июл. 2009 г., 07:16
почему вам нужна ваша пользовательская коллекция и вы не хотите использовать существующие?

Ответы на вопрос(5)

вы также можете наследовать от универсальной коллекции в неуниверсальный класс, например:

public class MyCollection : List<MyClass>
{

}

Таким образом, вы получаете всю функциональность списка (например). Вам просто нужно добавить несколько конструкторов.

 17 дек. 2012 г., 17:55

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Ашу, если вы хотите, чтобы некоторые операции проверки и добавления выполнялись, вы можете использовать универсальную коллекцию в качестве члена вашей специализированной коллекции:

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) { 
            }
        }
    }
}
 Ashish Ashu28 июл. 2009 г., 07:24
Так как я хочу проверить операцию удаления и удаления из коллекции. Это даст мне больше контроля, если я создам свою собственную коллекцию.
Решение Вопроса

List<T> несколько бессмысленно,especially теперь, когда у него естьIEnumerable<T> конструктор и наличие методов расширения. У него нет виртуальных методов, которые вы можете переопределить, кромеEquals, GetHashCode, а такжеToString, (Я полагаю, вы могли бы извлечь изList<T> если ваша цель состояла в том, чтобы реализовать функциональность Java toString () для списков.)

Если вы хотите создать свой собственный строго типизированный класс коллекции и, возможно, настроить поведение коллекции при добавлении / удалении элементов, вы хотите получить новый тип (для .NET 2.0)System.Collections.ObjectModel.Collection<T>, который защитил виртуальные методы, включаяInsertItem а такжеRemoveItem что вы можете переопределить для выполнения действий в это время. Обязательно прочитайте документацию - этоvery easy класс для создания, но вы должны понимать разницу между публичными / не виртуальными и защищенными / виртуальными методами. :)

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);
    }
}
 28 июл. 2009 г., 07:46
Гиперссылка прямо в тексте, но я также добавлю пример кода.
 Ashish Ashu28 июл. 2009 г., 07:36
Можете ли вы дать мне некоторую отправную точку или ссылку
 28 июл. 2009 г., 08:03
Хорошая точка зрения. Я запомню это. Вы получаете +1 за объяснение. Благодарю.
 28 июл. 2009 г., 07:52
@ Коби: Использование скрытия по имени в не виртуальных методах является гарантированным способом вызвать кошмар обслуживания. Как только кто-то оперирует им какICollection<T> вместоMyCollection, он сломан. Если метод не виртуальный, предположим, что любая попытка переопределить его будет ужасно неправильной.
 28 июл. 2009 г., 07:47
Пока ваши объекты явно определены как производный класс, например,MyCollection collection = new MyCollection();вам не нужно, чтобы методы были виртуальными. Вам это нужно только если у вас естьList<MyClass> collection = new MyCollection();и это не имеет большого смысла в этом случае. Я использую наследование здесь, чтобы получить функциональность, а не расширять класс. Тем не менее, хороший момент оCollection<T> учебный класс. Благодарю.

что было бы лучше использовать один из классов контейнеров, определенных в System.Collections.Generic.

Whether this approach is correct and new, as I working on .NET 3.5 framework. No. Use List or something instead. I want to expose this collection from my web service ( WCF) .How can I do that? pass. haven't used WCF. 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 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.
 28 июл. 2009 г., 08:58
По моему опыту, пока объект сериализуем, вы, вероятно, не столкнетесь с проблемами с WCF. Расширение List - это хорошо, если содержимое тоже сериализуемо. Просто обратите внимание: некоторые другие коллекции, такие как Словарь, не сериализуемы, но все еще возможно реализовать ваш собственный сериализуемый «Словарь». используя список.

я что-то здесь упускаю, но если вам просто нужно добавить проверки, почему вы не наследуете из универсальной коллекции и не переопределяете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);
    }

}
 Ashish Ashu28 июл. 2009 г., 09:17
Спасибо за объяснение. Не могли бы вы дать мне то, что является преимуществом или недостатком, которые я получаю при извлечении моей коллекции из System.Collections.ObjectModel.Collection & lt; T & gt; ???

Ваш ответ на вопрос