【问题标题】:Is there a type-safe ordered dictionary alternative? [duplicate]是否有类型安全的有序字典替代方案? [复制]
【发布时间】:2011-03-23 20:36:35
【问题描述】:

我想在字典中保存一些对。

最后我想将字典序列化为 JSON 对象。 然后我打印 JSON 内容。我希望这些对按照它们在字典中输入的顺序打印。

起初我用的是一本普通的字典。但后来我想可能不会保留订单。然后我迁移到 OrderedDictionary,但它不使用 Generic,这意味着它不是类型安全的。

您还有其他好的解决方案吗?

【问题讨论】:

标签: c# dictionary


【解决方案1】:

如果找不到替代品,并且不想更改正在使用的集合类型,最简单的方法可能是围绕 OrderedDictionary 编写类型安全的包装器。

它正在做你现在正在做的同样的工作,但非类型安全代码受到更多限制,仅在这一类中。在这个类中,我们可以依赖只包含 TKey 和 TValue 类型的支持字典,因为它只能从我们自己的 Add 方法中插入。在应用程序的其余部分,您可以将其视为类型安全的集合。

public class OrderedDictionary<TKey, TValue> : IDictionary<TKey, TValue> {
    private OrderedDictionary backing = new OrderedDictionary();

    // for each IDictionary<TKey, TValue> method, simply call that method in 
    // OrderedDictionary, performing the casts manually. Also duplicate any of 
    // the index-based methods from OrderedDictionary that you need.

    void Add(TKey key, TValue value)
    {
        this.backing.Add(key, value);
    }

    bool TryGetValue(TKey key, out TValue value)
    {
        object objValue;
        bool result = this.backing.TryGetValue(key, out objValue);
        value = (TValue)objValue;
        return result;
    }

    TValue this[TKey key]
    {
        get
        {
            return (TValue)this.backing[key];
        }
        set
        {
            this.backing[key] = value;
        }
    }
}

【讨论】:

【解决方案2】:

如果值的顺序很重要,请不要使用字典。我脑海中浮现的东西是 SortedDictionary 或 List&lt;KeyValuePair&gt;

【讨论】:

  • 对。 Dictionary 不会保留订单。 List&lt;KeyValuePair&gt; 是这里的关键。
  • SortedDictionary 不保留插入顺序,它强制排序!
  • @digEmAll 你是对的。我不完全确定 OP 想要什么。
  • @PeterOlson,如果订单很重要,我不同意您不应该使用字典。 OP的要求是有效的。字典的主要好处是强制唯一性和快速键查找。我可以设想一个你想要这些好处的情况,但你也想维护一个原始插入顺序的列表。您可以自己单独执行此操作,但 OrderedDictionary 在内部为您执行此操作。唯一缺少的是类型安全,可能是因为 MS 从不费心添加它。见stackoverflow.com/questions/2629027
  • 有许多使用模式,字典会添加但从未删除的项目。对于使用链桶散列的字典,以插入顺序维护项目的额外成本是最小的(在数组中使用索引链接列表往往比使用离散字典条目对象的引用链接列表更有效)。如果希望测试两个这样的字典是否匹配,并且如果它们匹配,它们很可能会以相同的顺序添加项目,那么按顺序枚举项目的能力可能会实现有用的优化。
【解决方案3】:

如果您可以根据键对其进行排序,那么SortedDictionary 可能适合您。 AFAIK 没有 OrderedDictionary 的通用实现,除非您实现一个。

【讨论】:

    【解决方案4】:

    由于 OrderedDictionary 没有 TryGetValue 方法,我不得不根据 David Yaw 的出色建议重写他的 TryGetValue。这是我的修改。

        bool TryGetValue(TKey key, out TValue value)
        {
            object objValue;
            value = default(TValue);
            try
            {
                objValue = this.backing[key];
                value = (TValue)objValue;
            }
            catch
            {
                return false;
            }
            return true;
        }
    

    【讨论】:

    • 使用Contains check 而不是try catch。
    猜你喜欢
    • 1970-01-01
    • 2011-02-05
    • 2011-01-09
    • 2013-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多