Можно ли исправить типизированный ArrayList в C #, как в C ++? - PullRequest
4 голосов
/ 02 марта 2010

У меня есть ArrayList, который содержит объекты фиксированного типа. Однако каждый раз, когда мне нужно извлечь объект определенного индекса, мне нужно типизировать его к моему определенному пользователем типу из типа объекта.

Есть ли способ в C # объявить ArrayList фиксированных типов точно так же, как в Java и C ++, или есть обходной путь, позволяющий избежать приведения типов каждый раз?

Edit:

Прошу прощения, я забыл упомянуть, что Мне требуется, чтобы структура данных была поточно-ориентированной, , а List - нет. В противном случае я бы просто использовал обычный Array. Но я хочу уберечь себя от попыток явной блокировки и разблокировки при записи массива.

Так что я подумал об использовании ArrayList, синхронизирую его, но каждый раз требуется типографская вставка.

Ответы [ 7 ]

6 голосов
/ 02 марта 2010

Вы можете использовать список . Класс List использует generics для создания строго типизированной коллекции.

Чтобы использовать, просто вызовите новый список <Тип, который вы хотите использовать> (), например:

List<string> myStringList = new List<string>();

В MSDN есть краткая статья о том, как сделать коллекции поточно-безопасными.

4 голосов
/ 02 марта 2010

Взгляните на System.Collections.Generic.List

http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx

3 голосов
/ 02 марта 2010

Вы смотрели на SynchronizedCollection ? Это в основном многопоточная версия List .

Обратите внимание, что эта коллекция является частью System.ServiceModel, так как она была добавлена ​​для поддержки диспетчеров каналов WCF. Это публичная коллекция, которая может использоваться любым кодом, однако, и находится в пространстве имен System.Collections.Generic. Все его методы и индексатор синхронизированы, поэтому вам не придется самостоятельно управлять блокировкой. Остерегайтесь LINQ, однако, так как перечислитель для этой коллекции не синхронизирован. Вам нужно будет заблокировать SyncRoot самостоятельно, если вы хотите использовать перечислитель или использовать LINQ:

var syncList = new SynchronizedCollection<int>();
// ...
lock(syncList.SyncRoot)
{
    var itemsInRange = syncList.Where(v => v > 100 && v < 1000);
}

Имейте в виду, что он использует жесткую блокировку (ключевое слово lock), и для многих потоков это не будет наиболее эффективным решением. Если у вас есть возможность использовать .NET 4.0, я бы посмотрел в новое пространство имен System.Collections.Concurrent для некоторых вкусных новых кусочков, таких как ConcurrentBag .

1 голос
/ 02 марта 2010

Общие списки FTW!

var items = new List<someType>();
1 голос
/ 02 марта 2010

Да, но вам нужно использовать Generics. Посмотрите на класс List в пространстве имен System.Collections.Generics.

0 голосов
/ 02 марта 2010

Используйте System.Collections.Generic.List<T>. Если вам нужен потокобезопасный режим, просто заблокируйте свойство SyncRoot в своей операции.

Какой-то код:

List<string> list = new List<string>();

lock (list.SyncRoot) {
   list.Add("Hello World");
}

Если вы обнаружите, что каждый раз блокировка раздражает, вы можете переопределить класс List и предоставить синхронизированный доступ к функциям-членам.

0 голосов
/ 02 марта 2010

Если вас беспокоит безопасность потоков, то, возможно, ConcurrentBag<T> подойдет:

Представляет потокобезопасный неупорядоченный набор объектов.

Примечание: для этого требуется .NET 4.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...