【问题标题】:Can I have fixed typed ArrayList in C#, just like C++?我可以像 C++ 一样在 C# 中修复类型化的 ArrayList 吗?
【发布时间】:2010-03-02 03:39:30
【问题描述】:

我有一个ArrayList,其中包含固定类型的对象。 但是,每次我需要将对象提取到特定索引时,我都需要将其从对象类型转换为我的用户定义类型。

在 C# 中是否有办法像 Java 和 C++ 一样声明固定类型的 ArrayList,或者是否有解决方法来避免每次都进行类型转换?

编辑:

抱歉,我忘了提到 我要求数据结构是线程安全的, List 不是。否则我只会使用普通的Array。但我想避免在编写数组时显式锁定和解锁。

于是就想到了用ArrayList,同步一下,但是每次都需要typecasting。

【问题讨论】:

标签: c# arraylist


【解决方案1】:

您可以使用List. List 类利用generics 来创建强类型集合。

要使用,只需像这样调用 new List() :

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

MSDN 有一篇快速文章,介绍了一些可以制作集合的方法thread safe.

【讨论】:

  • 对不起,我忘了提到我需要数据结构是线程安全的,我认为 List 不是线程安全的,如果我错了,请纠正我
  • @Kazoom 更新了 MSDN 关于收集线程安全的文章。
【解决方案2】:

看看 System.Collections.Generic.List

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

【讨论】:

  • 对不起,我忘了提到我需要数据结构是线程安全的
【解决方案3】:

你看过SynchronizedCollection<T>吗?它基本上是 List 的线程安全版本。

请注意,此集合是 System.ServiceModel 的一部分,因为添加它是为了支持 WCF 的通道调度程序。它是一个公共集合,任何代码都可以使用它,并且位于 System.Collections.Generic 命名空间中。它的所有方法和索引器都是同步的,因此您不必自己管理锁定。但是,请注意 LINQ,因为此集合的枚举器是同步的。如果您希望使用枚举器或使用 LINQ,则需要自己锁定 SyncRoot:

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<T>

【讨论】:

    【解决方案4】:

    是的,但您需要使用泛型。查看 System.Collections.Generics 命名空间中的 List 类。

    【讨论】:

    • 对不起,我忘了提到我需要数据结构是线程安全的,我认为 List 不是线程安全的,如果我错了,请纠正我
    • 这种类型的公共静态成员是线程安全的。 msdn.microsoft.com/en-us/library/6sh2ey19.aspx
    • @ec - 不是真的。我不明白那篇文章为什么这么说,但在它下面说“只要不修改集合,List(T) 可以同时支持多个读取器。通过集合枚举本质上不是线程安全的过程。在枚举与一个或多个写访问竞争的极少数情况下,确保线程安全的唯一方法是在整个枚举期间锁定集合。为了允许多个线程访问集合进行读写,您必须实现您自己的同步。”
    【解决方案5】:

    通用列表 FTW!

    var items = new List<someType>();
    

    【讨论】:

    • 对不起,我忘了提到我需要数据结构是线程安全的,我认为 List 不是线程安全的,如果我错了,请纠正我
    • 这种类型的公共静态成员是线程安全的。 msdn.microsoft.com/en-us/library/6sh2ey19.aspx
    【解决方案6】:

    使用System.Collections.Generic.List&lt;T&gt;。如果您想要线程安全,只需在操作中锁定SyncRoot 属性即可。

    一些代码:

    List<string> list = new List<string>();
    
    lock (list.SyncRoot) {
       list.Add("Hello World");
    }
    

    如果您发现每次锁定都很烦人,您可以重写 List 类并提供对成员函数的同步访问。

    【讨论】:

      【解决方案7】:

      如果您关心线程安全,那么ConcurrentBag&lt;T&gt; 可能会解决问题:

      表示线程安全、无序的对象集合。

      注意:这需要 .NET 4。

      【讨论】:

        猜你喜欢
        • 2012-07-25
        • 2015-06-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-24
        • 2018-02-04
        • 2011-04-23
        • 1970-01-01
        相关资源
        最近更新 更多