CollectionBase vs generics

17

Я переношу приложение с .NET 1.1 на .NET 2.0. Должен ли я удалить все виды использования CollectionBase? Если да, то какова наилучшая стратегия миграции?

    
задан leora 22.11.2008 в 11:38
источник

3 ответа

22

Да, лучшие классы, на которые нужно обратить внимание, находятся в System.Collections.Generic.
Обычно я использую List.

Есть два подхода, которые вы можете использовать:

А

public class MyClass
{
  public List<MyItem> Items;
}

В

public class MyItemCollection : List<MyItem>
{
}

public class MyClass
{
  public MyItemCollection Items;
}

Эти два подхода отличаются очень незначительно, и вам нужно использовать метод (B), если вы планируете расширить функциональность List.

Вот ссылка на дополнительную информацию: Ссылка

Что касается уже реализованных классов, вы можете удалить все функции, указанные в интерфейсе IList. например.

public int Add(InstrumentTradeDataRow instTrade) { return List.Add(instTrade); }

Это можно удалить, потому что List уже реализует для вас безопасную функцию добавления типа.

См. эту ссылку для получения дополнительной информации:
Ссылка     

ответ дан Mark Ingram 22.11.2008 в 11:41
источник
  • вы можете привести мне пример. , –  leora 22.11.2008 в 11:43
  • Выполнено. Что еще вы хотели бы увидеть? –  Mark Ingram 22.11.2008 в 11:45
  • Что мне делать с существующим кодом: public int Add (InstrumentTradeDataRow instTrade) {return List.Add (instTrade); } –  leora 22.11.2008 в 11:46
  • Если вы собираетесь сделать опцию ... убедитесь, что вы реализуете ICollection. –  Timothy Khouri 22.11.2008 в 12:36
  • Если вы хотите выполнить реализацию, вы должны действительно подклассы Collection <T>, в противном случае нет виртуальных методов ... плюс LINQ в любом случае предоставляет отсутствующую функциональность (Find и т. д.). –  Marc Gravell♦ 23.11.2008 в 16:21
16

Как правило, List<T> делает большую часть того, что вы обычно хотите. Если вы хотите настроить поведение, вы должны наследовать от Collection<T> - у этого есть методы virtual , чтобы вы могли настраивать поведение при добавлении / удалении / обновлении и т. Д. Вы не можете сделать это с List<T> , так как нет (uesful ) virtual .

    
ответ дан Marc Gravell 23.11.2008 в 14:18
источник
  • К сожалению Collection <T> .Add не является виртуальным, хотя это определенно должно быть. –  abatishchev 24.09.2010 в 08:16
  • @abatishchev - нет, но InsertItem (который обрабатывает Add и Insert), как и SetItem (который обрабатывает повторное назначение) –  Marc Gravell♦ 24.09.2010 в 09:26
  • Да, вы правы, я поспешил, спасибо! –  abatishchev 24.09.2010 в 09:27
1

Я предпочитаю подход Mark Ingrams A), возможно, с базовым классом, который вы пишете сами.

Есть еще одна проблема с переносом на дженерики; преобразование имеет тенденцию иметь определенный вирусный эффект. Вы не сможете остановиться, пока не пройдете весь путь. Если вы THUUGHT вы собираетесь потратить пару часов на выполнение НЕКОТОРЫХ дженериков, вы часто будете тратить несколько дней на ВСЕ ДРУГИЕ дженерики.

Вы можете / должны избегать этого, предоставляя вашим новым операторам перегрузку классов в / из списка

public static implicit operator MyClass(List m) 
{
   // code to convert from m to MyClass
}

public static explicit operator List(MyClass m) 
{
    // code to convert from MyClass list
}

Это действительно просто остановки. Вы можете использовать «найти способы их использования» на любом последующем этапе, чтобы определить, какие места не были полностью преобразованы. Когда все способы использования удаляются, вы можете удалить приведения.

Я вообще предпочитаю сделать бросок из MyClass в List явным (это то, как вы не хотите идти), а другое неявное.

Лучшим подходом было бы, как правило, начать в верхней части ваших слоев, рядом с уровнем представления и работать вниз. (Это противоположно тому, что вы могли бы подумать. Если вы сделаете актерский состав из MyClass в список неявным, не имеет значения, с какого конца вы начинаете)

    
ответ дан krosenvold 22.11.2008 в 12:22
источник