【问题标题】:Which Collection Class to use: Hashtable or Dictionary?使用哪个集合类:哈希表还是字典?
【发布时间】:2010-11-28 20:32:24
【问题描述】:

我需要定义一个具有内部集合对象的类,以通过字符串键保存不同类型的值(如字符串、int、float、DateTime 和 bool)。我可以使用 Hashtable,因为它不是强类型集合类,而 Dictionary 用于强类型项目(即使我可以将对象用于 Dictionary)。

这是我想定义我的类及其用法的情况:

 public class MyBaseClass<D> {
   protected Hashtable ht = new Hashtable();

   MyClass public SetValue<T>(string key, T value)
   {
       ht.Add(key, value);
       return this;
   }

   public abstract D GetObject();
 }

 // Example of using the base class for data as class Data1
 public MyClass<Data1> : MyBaseClass<Data1> {
      public Data1 GetObject() {
         return new Data1 {
             Property1 = ht["key1"] as string,
             Property2 = Int.Parse(ht["key2"].ToString())
          }
 }

对于上面的例子,我不确定在 MyBaseClass 中保存数据的最佳集合是什么?我读了一些关于 Hashtable 的文章。它是一个过时的集合,与 Dictionary 集合相比,性能要慢得多。我应该使用 Dictionary 还是 .Net 3.5 中可用的任何其他集合?

【问题讨论】:

  • 字典是一个优化的哈希表。我认为这回答了你的问题:)

标签: c# collections dictionary


【解决方案1】:

在这种情况下,我个人会使用Dictionary&lt;string, object&gt;。 至少这会阻止你尝试使用非字符串键。

我个人也会停止使用受保护字段 - 考​​虑使用受保护的 setter 和公共 getter 将索引器添加到您的基类:

public object this[string key]
{
    get { return ht[key]; }
    protected set { ht[key] = value; }
}

如果您希望它在通过丢失密钥访问时返回null,您应该在getter 中使用TryGetValue。同样,如果您想在添加重复键时失败,您可以在设置器中使用Add

【讨论】:

  • 其实在这种情况下,我并不关心 null 或异常。如果我尝试获取尚未设置的值,我想获得异常。
  • 在这种情况下,我发布的代码就可以了。如果您对 setting 使用相同的键两次,它只会覆盖以前的值。
  • @Jon Skeet,谢谢你的信息。我可以使用这个覆盖特性来读取另一组属性,然后根据新的集合数据创建一个新的 obj。换句话说,我可以在循环或方法调用中重用实例(循环或方法调用是一种具有不同值的重复)。
  • 使用对象的其他替代方法是什么? This(object) 在性能方面非常糟糕,因为它们必须被装箱/拆箱。这让我们回到了泛型前……
  • @River:当然,只有值类型需要装箱/拆箱。至于“性能相当差”——当我有证据表明这是性能瓶颈时,我只会担心这一点。你真的必须经常调用它才能成为一个问题。
【解决方案2】:

您应该始终使用泛型集合,除非有充分的理由不这样做。这确保了一切都是合理的类型安全并减少编程错误。如果将值类型存储在通用字典中,也会有性能优势;如果你使用 Hashtable,每个值类型都必须被装箱。

但是,您的示例似乎本质上是类型不安全的,并且有一种代码味道。你有两个类型变量来访问同一个哈希表有什么特别的原因吗?

【讨论】:

    【解决方案3】:

    哈希表存在于 1.1 中。直到泛型在 2.0 中出现,字典才存在。我认为没有任何理由在 2.0 及更高版本中使用 Hashtable - 它本质上是一个硬编码 Dictionary ,它(可能?)只是为了让移植的 1.1 代码工作。

    所以,字典应该是您在这里选择的对象。

    【讨论】:

      【解决方案4】:

      我会使用字典,但我真的想让我的集合类型安全,我可能会实现Item 29 of Effective Java 中描述的类型安全的异构容器(示例适用于 Java,但应用程序应该适用于两种语言,尽管细节和限制可能不同)。这种技术将值的类型编码到键中。

      【讨论】:

      【解决方案5】:

      我会选择字典。我只能想到 Hashtable 可能 更受青睐的一种情况。对于一个写入器和多个读取器来说,它是线程安全的,无需使用同步机制。但是,这种情况将非常具体且非常罕见。即便如此,我也可能会使用 Dictionary 并使用所有正常的同步原语。

      【讨论】:

        猜你喜欢
        • 2016-08-12
        • 2013-11-29
        • 2015-02-12
        • 2012-07-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多