c#中的多键字典? [复制]

Posted

技术标签:

【中文标题】c#中的多键字典? [复制]【英文标题】:Multi-key dictionary in c#? [duplicate] 【发布时间】:2010-11-13 09:30:49 【问题描述】:

我知道 BCL 中没有一个,但谁能指出一个好的开源代码?

Multi 我的意思是 2 个键。 ;-)

【问题讨论】:

您想要一个由多个属性组成的键,还是希望它可以使同一个键可以在同一个字典中多次存在?这些是不同的。 ***.com/questions/689940/… 您可能想添加一个示例用法,以阐明您的意思。 这些值得一看:noocyte.wordpress.com/2008/02/18/double-key-dictionary 和 codeproject.com/Articles/32894/C-Multi-key-Generic-Dictionary 没有 +1 让问题变得如此简短和模糊。您的问题可以通过 10 种不同的方式暗示 【参考方案1】:

我目前只是将键连接成一个字符串作为一种解决方法。当然,这不适用于非字符串键。也很想知道答案。

【讨论】:

因为在大多数类上 .ToSting() 对于所有值(即类型名称)都是相同的。并非所有类型都具有有效的字符串表示等。 那么,不能使用密封类作为键,而不是实现一个由多个元组组成的类,而是必须继承许多类。 是的,太多的 BCL 类没有实现 ToString,这意味着您不能假设 ToString 将返回给定类型状态的唯一表示。 TL;DR:失败 使用字符串连接可能很危险。例如,如果您有整数 123 和 456,并将它们连接起来创建一个键,这将给出“123456”。如果你有 12 和 3456 并将它们连接起来,你会得到......“123456”。哎呀。 @Meta-Knight 使用分隔符。呵呵。【参考方案2】:

我使用Tuple 作为Dictionary 中的键。

public class Tuple<T1, T2> 
    public T1 Item1  get; private set; 
    public T2 Item2  get; private set; 

    // implementation details

确保覆盖 EqualsGetHashCode 并根据需要定义 operator!=operator==。您可以根据需要扩展Tuple 以容纳更多项目。 .NET 4.0 将包含一个内置的Tuple

【讨论】:

查看这篇关于多个“多键”字典实现之间的性能测试的博文here @AronW 据我所知,这篇博文从未使用Tuple 作为密钥? 如果你要编写自己的 Tuple 类,不妨使用命名项而不是 T1、T2...【参考方案3】:

元组将(是)在 .Net 4.0 之前,您还可以使用

 Dictionary<key1, Dictionary<key2, TypeObject>> 

或者,创建一个自定义集合类来表示这个......

 public class TwoKeyDictionary<K1, K2, T>: 
        Dictionary<K1, Dictionary<K2, T>>  

或者,用三个键...

public class ThreeKeyDictionary<K1, K2, K3, T> :
    Dictionary<K1, Dictionary<K2, Dictionary<K3, T>>>  

【讨论】:

绝妙的答案——这非常适合我的需求。 这不是多键字典,这是一个非常糟糕的元组键字典实现,因为你不能通过第二个键访问值,没有它你也不能访问它们(除非你得到它由内部字典的值组成,但它可以包含多个项目)。此外,您的解决方案缺少用于添加和删除项目的代码。 天啊...我什至不确定您在说什么。您希望多键字典能够使用 either 键访问对象吗?这绝不等同于操作要求的元组。对你来说,你真的期望一个完全充实的专业实施,所有的花里胡哨,作为问题的答案?做梦吧,我为此得到报酬。编写自己的代码。【参考方案4】:

看看 Wintellect 的 PowerCollections (CodePlex download)。我认为他们的 MultiDictionary 就是这样做的。

这是一个字典字典,所以你有 2 个键来访问每个对象,主字典的键为你获取所需的子字典,然后是子字典的第二个键以获取所需的项目。是这个意思吗?

【讨论】:

他们的MultiDictionary&lt;,&gt; 允许为单个键分配多个值,而不是在这个意义上有多个键。 但 OP 的问题尽可能模糊。因此 +1 表示不同的看法。 @pbalaga 是对的,PowerCollections 不允许您拥有两个键(因此被否决)【参考方案5】:

我认为你需要一个 Tuple2 类。确保它的 GetHashCode() 和 Equals() 是基于这两个包含的元素。

见Tuples in C#

【讨论】:

【参考方案6】:

有什么问题吗

新字典, object>
?

【讨论】:

有内置的 Pair 类吗? @MichaelDonohue:从 .NET 4.0 开始,有 Tuple 类。 是的,有一点不对:KVP使用ValueType.GetHashCode - "如果调用派生类型的GetHashCode方法,返回值不太可能适合用作哈希表中的键。 " KVP 对于 Dictionary 键来说是一个完全不合适的选择,并且可能会产生很多冲突。【参考方案7】:

我也像jason in his answer 那样使用元组。但是,我建议您将元组简单地定义为结构:

public struct Tuple<T1, T2> 
    public readonly T1 Item1;
    public readonly T2 Item2;
    public Tuple(T1 item1, T2 item2)  Item1 = item1; Item2 = item2; 


public static class Tuple  // for type-inference goodness.
    public static Tuple<T1,T2> Create<T1,T2>(T1 item1, T2 item2)  
        return new Tuple<T1,T2>(item1, item2); 
    

您可以免费获得不变性,.GetHashcode.Equals,这(在您等待 C# 4.0 时)非常简单......

一个警告但是:默认的GetHashcode 实现(有时)only considers the first field 所以请确保使第一个字段最具区分性或自己实现GetHashcode(例如使用FieldwiseHasher.Hash(this) from ValueUtils),否则您可能会遇到可扩展性问题。

此外,您可以避免使事情复杂化的空值(如果您真的想要空值,只需将 Tuple&lt;&gt; 设为可空值)。有点跑题了,我是唯一一个对框架级别缺乏对非空引用的支持感到恼火的人吗?我在大型项目上工作,偶尔会有一个空值出现在它确实不应该出现的地方——嘿,你会得到一个空引用异常——但是有一个堆栈跟踪可以指向引用的第一次使用,而不是实际错误的代码.

当然,.NET 4.0 现在已经很老了;我们大多数人都可以使用 .NET 4.0 的元组。

编辑: 解决 .NET 为我编写的 ValueUtils 的结构提供的糟糕的 GetHashCode 实现,它还允许您使用真实姓名您的多字段键;这意味着您可能会写如下内容:

sealed class MyValueObject : ValueObject<MyValueObject> 
    public DayOfWeek day;
    public string NamedPart;
    //properties work fine too

...这有望使具有值语义的数据更容易获得人类可读的名称,至少在 some future version of C# implements proper tuples with named members 之前;希望有不错的哈希码;-)。

【讨论】:

关于 .NET 中元组的引用与值类型决策的精彩介绍:msdn.microsoft.com/en-us/magazine/dd942829.aspx#id0400060 @nawfal:我决定重新实现哈希码函数生成器。有用;但它仍然很准系统:github.com/EamonNerbonne/ValueUtils @EamonNerbonne 看起来不错。我不太确定OverriddenHashCodeMethod 的工作。将不得不测试。 @nawfal:我会完善它并添加更多功能,然后将其发布到 nuget。如果您真的打算使用它,我很乐意提供有关如何使其适用于您的用例的反馈 - 请随时在 github 上发表评论! @nawfal:好的,我认为它现在处于非常可用的状态。我很想听听您对两个具体设计问题的看法:github.com/EamonNerbonne/ValueUtils/issues/1 和 github.com/EamonNerbonne/ValueUtils/issues/2。即便如此,这已准备好实际使用 - 只需尝试引用 nuget:ValueUtils,然后创建您的类 ala sealed class MyClass : ValueObject&lt;MyClass&gt;!早期的性能测试表明它比 ValueType 快得​​多,比 Tuple&lt;&gt; 快得多,并且在手动代码的 2 倍以内。【参考方案8】:

我用谷歌搜索了这个:http://www.codeproject.com/KB/recipes/multikey-dictionary.aspx。我想与使用 struct 在常规字典中包含 2 个键相比,它的主要特点是您以后可以通过其中一个键进行引用,而不必提供 2 个键。

【讨论】:

【参考方案9】:

你能用Dictionary&lt;TKey1,Dictionary&lt;TKey2,TValue&gt;&gt;吗?

你甚至可以继承这个:

public class DualKeyDictionary<TKey1,TKey2,TValue> : Dictionary<TKey1,Dictionary<TKey2,TValue>>

编辑:这是一个重复的答案。它的实用性也受到限制。虽然它确实“工作”并提供编码dict[key1][key2] 的能力,但有很多“解决方法”可以让它“正常工作”。

但是:只是为了好玩,尽管如此,仍然可以实现 Dictionary,但在这一点上它变得有点冗长:

public class DualKeyDictionary<TKey1, TKey2, TValue> : Dictionary<TKey1, Dictionary<TKey2, TValue>> , IDictionary< object[], TValue >

    #region IDictionary<object[],TValue> Members

    void IDictionary<object[], TValue>.Add( object[] key, TValue value )
    
        if ( key == null || key.Length != 2 )
            throw new ArgumentException( "Invalid Key" );

        TKey1 key1 = key[0] as TKey1;
        TKey2 key2 = key[1] as TKey2;

        if ( !ContainsKey( key1 ) )
            Add( key1, new Dictionary<TKey2, TValue>() );

        this[key1][key2] = value;
    

    bool IDictionary<object[], TValue>.ContainsKey( object[] key )
    
        if ( key == null || key.Length != 2 )
            throw new ArgumentException( "Invalid Key" );

        TKey1 key1 = key[0] as TKey1;
        TKey2 key2 = key[1] as TKey2;

        if ( !ContainsKey( key1 ) )
            return false;

        if ( !this[key1].ContainsKey( key2 ) )
            return false;

        return true;
    

【讨论】:

我明白了,Charles 也在想同样的事情。然而,这些问题在于分配。这可能是一个难以管理的野兽。 +1 为命名,DualKey..一直在寻找一个好名字:)【参考方案10】:

这是一个对类的充实示例,它可以用作Dictionary 的键。

public class Pair<T1, T2>

    public T1 Left  get; private set; 
    public T2 Right  get; private set; 

    public Pair(T1 t1, T2 t2)
    
        Left = t1;
        Right = t2;
    

    public override bool Equals(object obj)
    
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != typeof(Pair<T1, T2>)) return false;
        return Equals((Pair<T1, T2>)obj);
    

    public bool Equals(Pair<T1, T2> obj)
    
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        return Equals(obj.Left, Left) && Equals(obj.Right, Right);
    

    public override int GetHashCode()
    
        unchecked
        
            return (Left.GetHashCode() * 397) ^ Right.GetHashCode();
        
    

【讨论】:

【参考方案11】:

我经常使用它,因为它很短并且提供了我需要的语法糖......

public class MultiKeyDictionary<T1, T2, T3> : Dictionary<T1, Dictionary<T2, T3>>

    new public Dictionary<T2, T3> this[T1 key]
    
        get
        
            if (!ContainsKey(key))
                Add(key, new Dictionary<T2, T3>());

            Dictionary<T2, T3> returnObj;
            TryGetValue(key, out returnObj);

            return returnObj;
        
    

使用它:

dict[cat][fish] = 9000;

“Cat”键也不必存在。

【讨论】:

我还应该提到,用另一个类 创建进一步的嵌套是任意的:Dictionary> 等。另外,我避免使用它,但它可以很好地清理时髦的嵌套字典。 检查 [cat][fish] 或 [cat][mouse] 键是否存在的好方法是什么? @goku_da_master dict[cat].ContainsKey(mouse) 如果 cat 不存在,你总是得到错误,因为它是新的。如果您经常以这种方式使用它,我会对其进行基准测试 - 这不会是一种非常优化的方式。 被低估的解决方案! (: 使用 4.0 之前的 .NET 时非常方便。【参考方案12】:

我编写并成功使用了它。

public class MultiKeyDictionary<K1, K2, V> : Dictionary<K1, Dictionary<K2, V>>  

    public V this[K1 key1, K2 key2] 
        get 
            if (!ContainsKey(key1) || !this[key1].ContainsKey(key2))
                throw new ArgumentOutOfRangeException();
            return base[key1][key2];
        
        set 
            if (!ContainsKey(key1))
                this[key1] = new Dictionary<K2, V>();
            this[key1][key2] = value;
        
    

    public void Add(K1 key1, K2 key2, V value) 
            if (!ContainsKey(key1))
                this[key1] = new Dictionary<K2, V>();
            this[key1][key2] = value;
    

    public bool ContainsKey(K1 key1, K2 key2) 
        return base.ContainsKey(key1) && this[key1].ContainsKey(key2);
    

    public new IEnumerable<V> Values 
        get 
            return from baseDict in base.Values
                   from baseKey in baseDict.Keys
                   select baseDict[baseKey];
        
     




public class MultiKeyDictionary<K1, K2, K3, V> : Dictionary<K1, MultiKeyDictionary<K2, K3, V>> 
    public V this[K1 key1, K2 key2, K3 key3] 
        get 
            return ContainsKey(key1) ? this[key1][key2, key3] : default(V);
        
        set 
            if (!ContainsKey(key1))
                this[key1] = new MultiKeyDictionary<K2, K3, V>();
            this[key1][key2, key3] = value;
        
    

    public bool ContainsKey(K1 key1, K2 key2, K3 key3) 
        return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3);
    


public class MultiKeyDictionary<K1, K2, K3, K4, V> : Dictionary<K1, MultiKeyDictionary<K2, K3, K4, V>> 
    public V this[K1 key1, K2 key2, K3 key3, K4 key4] 
        get 
            return ContainsKey(key1) ? this[key1][key2, key3, key4] : default(V);
        
        set 
            if (!ContainsKey(key1))
                this[key1] = new MultiKeyDictionary<K2, K3, K4, V>();
            this[key1][key2, key3, key4] = value;
        
    

    public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4) 
        return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4);
    


public class MultiKeyDictionary<K1, K2, K3, K4, K5, V> : Dictionary<K1, MultiKeyDictionary<K2, K3, K4, K5, V>> 
    public V this[K1 key1, K2 key2, K3 key3, K4 key4, K5 key5] 
        get 
            return ContainsKey(key1) ? this[key1][key2, key3, key4, key5] : default(V);
        
        set 
            if (!ContainsKey(key1))
                this[key1] = new MultiKeyDictionary<K2, K3, K4, K5, V>();
            this[key1][key2, key3, key4, key5] = value;
        
    

    public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5) 
        return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5);
    


public class MultiKeyDictionary<K1, K2, K3, K4, K5, K6, V> : Dictionary<K1, MultiKeyDictionary<K2, K3, K4, K5, K6, V>> 
    public V this[K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6] 
        get 
            return ContainsKey(key1) ? this[key1][key2, key3, key4, key5, key6] : default(V);
        
        set 
            if (!ContainsKey(key1))
                this[key1] = new MultiKeyDictionary<K2, K3, K4, K5, K6, V>();
            this[key1][key2, key3, key4, key5, key6] = value;
        
    
    public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6) 
        return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6);
    


public class MultiKeyDictionary<K1, K2, K3, K4, K5, K6, K7, V> : Dictionary<K1, MultiKeyDictionary<K2, K3, K4, K5, K6, K7, V>> 
    public V this[K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7] 
        get 
            return ContainsKey(key1) ? this[key1][key2, key3, key4, key5, key6, key7] : default(V);
        
        set 
            if (!ContainsKey(key1))
                this[key1] = new MultiKeyDictionary<K2, K3, K4, K5, K6, K7, V>();
            this[key1][key2, key3, key4, key5, key6, key7] = value;
        
    
    public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7) 
        return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7);
    


public class MultiKeyDictionary<K1, K2, K3, K4, K5, K6, K7, K8, V> : Dictionary<K1, MultiKeyDictionary<K2, K3, K4, K5, K6, K7, K8, V>> 
    public V this[K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8] 
        get 
            return ContainsKey(key1) ? this[key1][key2, key3, key4, key5, key6, key7, key8] : default(V);
        
        set 
            if (!ContainsKey(key1))
                this[key1] = new MultiKeyDictionary<K2, K3, K4, K5, K6, K7, K8, V>();
            this[key1][key2, key3, key4, key5, key6, key7, key8] = value;
        
    
    public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8) 
        return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8);
    


public class MultiKeyDictionary<K1, K2, K3, K4, K5, K6, K7, K8, K9, V> : Dictionary<K1, MultiKeyDictionary<K2, K3, K4, K5, K6, K7, K8, K9, V>> 
    public V this[K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8, K9 key9] 
        get 
            return ContainsKey(key1) ? this[key1][key2, key3, key4, key5, key6, key7, key8, key9] : default(V);
        
        set 
            if (!ContainsKey(key1))
                this[key1] = new MultiKeyDictionary<K2, K3, K4, K5, K6, K7, K8, K9, V>();
            this[key1][key2, key3, key4, key5, key6, key7, key8, key9] = value;
        
    
    public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8, K9 key9) 
        return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8, key9);
    


public class MultiKeyDictionary<K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, V> : Dictionary<K1, MultiKeyDictionary<K2, K3, K4, K5, K6, K7, K8, K9, K10, V>> 
    public V this[K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8, K9 key9, K10 key10] 
        get 
            return ContainsKey(key1) ? this[key1][key2, key3, key4, key5, key6, key7, key8, key9, key10] : default(V);
        
        set 
            if (!ContainsKey(key1))
                this[key1] = new MultiKeyDictionary<K2, K3, K4, K5, K6, K7, K8, K9, K10, V>();
            this[key1][key2, key3, key4, key5, key6, key7, key8, key9, key10] = value;
        
    
    public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8, K9 key9, K10 key10) 
        return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8, key9, key10);
    


public class MultiKeyDictionary<K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, V> : Dictionary<K1, MultiKeyDictionary<K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, V>> 
    public V this[K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8, K9 key9, K10 key10, K11 key11] 
        get 
            return ContainsKey(key1) ? this[key1][key2, key3, key4, key5, key6, key7, key8, key9, key10, key11] : default(V);
        
        set 
            if (!ContainsKey(key1))
                this[key1] = new MultiKeyDictionary<K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, V>();
            this[key1][key2, key3, key4, key5, key6, key7, key8, key9, key10, key11] = value;
        
    
    public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8, K9 key9, K10 key10, K11 key11) 
        return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8, key9, key10, key11);
    

【讨论】:

我为这个答案写了一个ToMultiKeyDictionary() 扩展和posted it as an answer below 这在元组不可用的 Unity 中效果很好!!!请注意,您需要using System.Linq;【参考方案13】:

这是我的实现。我想要一些东西来隐藏元组概念的实现。

  public class TwoKeyDictionary<TKey1, TKey2, TValue> : Dictionary<TwoKey<TKey1, TKey2>, TValue>
  
    public static TwoKey<TKey1, TKey2> Key(TKey1 key1, TKey2 key2)
    
      return new TwoKey<TKey1, TKey2>(key1, key2);
    

    public TValue this[TKey1 key1, TKey2 key2]
    
      get  return this[Key(key1, key2)]; 
      set  this[Key(key1, key2)] = value; 
    

    public void Add(TKey1 key1, TKey2 key2, TValue value)
    
      Add(Key(key1, key2), value);
    

    public bool ContainsKey(TKey1 key1, TKey2 key2)
    
      return ContainsKey(Key(key1, key2));
    
  

  public class TwoKey<TKey1, TKey2> : Tuple<TKey1, TKey2>
  
    public TwoKey(TKey1 item1, TKey2 item2) : base(item1, item2)  

    public override string ToString()
    
      return string.Format("(0,1)", Item1, Item2);
    
  

它有助于使用法看起来像字典

item.Add(1, "D", 5.6);

value = item[1, "D"];

【讨论】:

如何遍历所有?【参考方案14】:

如果有人正在寻找ToMultiKeyDictionary(),这里的实现应该适用于此处的大多数答案(基于Herman's):

public static class Extensions_MultiKeyDictionary 

    public static MultiKeyDictionary<K1, K2, V> ToMultiKeyDictionary<S, K1, K2, V>(this IEnumerable<S> items, Func<S, K1> key1, Func<S, K2> key2, Func<S, V> value) 
        var dict = new MultiKeyDictionary<K1, K2, V>(); 
        foreach (S i in items)  
            dict.Add(key1(i), key2(i), value(i)); 
         
        return dict; 
    

    public static MultiKeyDictionary<K1, K2, K3, V> ToMultiKeyDictionary<S, K1, K2, K3, V>(this IEnumerable<S> items, Func<S, K1> key1, Func<S, K2> key2, Func<S, K3> key3, Func<S, V> value) 
        var dict = new MultiKeyDictionary<K1, K2, K3, V>(); 
        foreach (S i in items)  
            dict.Add(key1(i), key2(i), key3(i), value(i)); 
         
        return dict; 
    

【讨论】:

【参考方案15】:

这里有很多好的解决方案, 我这里缺少的是基于Tuple 类型构建的实现,所以我自己写了一个。

由于它只是继承自 Dictionary&lt;Tuple&lt;T1,T2&gt;, T&gt;,因此您始终可以同时使用这两种方式。

var dict = new Dictionary<int, int, Row>();
var row = new Row();
dict.Add(1, 2, row);
dict.Add(Tuple.Create(1, 2, row));
dict.Add(new Tuple<int, int>(1, 2));

这是代码。

public class Dictionary<TKey1,TKey2,TValue> :  Dictionary<Tuple<TKey1, TKey2>, TValue>, IDictionary<Tuple<TKey1, TKey2>, TValue>


    public TValue this[TKey1 key1, TKey2 key2]
    
        get  return base[Tuple.Create(key1, key2)]; 
        set  base[Tuple.Create(key1, key2)] = value; 
    

    public void Add(TKey1 key1, TKey2 key2, TValue value)
    
        base.Add(Tuple.Create(key1, key2), value);
    

    public bool ContainsKey(TKey1 key1, TKey2 key2)
    
        return base.ContainsKey(Tuple.Create(key1, key2));
    

请注意,此实现依赖于 Tuple.Equals() 实现本身:

http://msdn.microsoft.com/en-us/library/dd270346(v=vs.110).aspx

obj参数在以下情况下被认为等于当前实例:

它是一个元组对象。 它的两个组件与当前实例的类型相同。 它的两个组件与当前实例的组件相同。相等性由每个组件的默认对象相等性比较器确定。

【讨论】:

简单好用,谢谢。 非常好的解决方案【参考方案16】:

这是另一个将 Tuple 类与 Dictionary 结合使用的示例。

        // Setup Dictionary
    Dictionary<Tuple<string, string>, string> testDictionary = new Dictionary<Tuple<string, string>, string>
    
        new Tuple<string, string>("key1","key2"), "value1",
        new Tuple<string, string>("key1","key3"), "value2",
        new Tuple<string, string>("key2","key3"), "value3"
    ;
    //Query Dictionary
    public string FindValue(string stuff1, string stuff2)
    
        return testDictionary[Tuple.Create(stuff1, stuff2)];
    

【讨论】:

以上是关于c#中的多键字典? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

wpf中的多键手势

c#多键字典,用自己的可变类替换元组时出现“KeyNotFoundException”[重复]

python字典多键值及重复键值的使用方法(详解)

python之itemgetter函数:对字典列表进行多键排序

MySQL 多键

字典操作中的奇怪行为以及 Python 中的多处理