C#中如何实现一个键对应多个值的字典?

18

我经常需要一个键对应多个值的字典,但在C#中,大多数字典都是二维的,比如Dictionary和Hashtable。

我想要像这样的东西:

var d = new Dictionary<key-dt,value1-dt,value2-dt,value3-dt,value4-dt>();

dt 在<> 里面表示数据类型。有人对此有想法吗?


2
我假设你想要一个键值对,其中值是一个列表?可以这样做:var d = new Dictionary<string, List<object>>(); 或者你想要存储的任何列表。 - Justin Chmura
2
你需要更好地解释你想要什么。目前的解释并没有真正说明任何事情。请举一个你可能会使用所设想的字典的例子。 - Pete
字典需要2个参数,那么你最终想要实现什么呢? - MethodMan
谢谢Justin,你是对的。由于我的内容中有一些特殊字符,它在这里显示不正确。 - diwatu
参考这个类似的问题,获取一些想法:https://dev59.com/sHRB5IYBdhLWcg3wNk53 - Drahcir
显示剩余4条评论
4个回答

30

字典是一个键值对,其中根据键获取值。所有键都是唯一的。

现在,如果您想要一个具有1个键类型和多个值类型的Dictionary,则有几个选项:

第一个是使用Tuple

var dict = new Dictionary<KeyType, Tuple<string, string, bool, int>>()

另一个选项是使用(C# 4.0及以上版本):

var dict = new Dictionary<KeyType, dynamic>()

System.Dynamic.ExpandoObject可以具有任何类型的值。

using System;
using System.Linq;
using System.Collections.Generic;

public class Test {
   public static void Main(string[] args) {
        dynamic d1 = new System.Dynamic.ExpandoObject();
    var dict = new Dictionary<int, dynamic>();
        dict[1] = d1;
        dict[1].FooBar = "Aniket";
        Console.WriteLine(dict[1].FooBar);
        dict[1].FooBar = new {s1="Hello", s2="World", s3=10};
        Console.WriteLine(dict[1].FooBar.s1);
        Console.WriteLine(dict[1].FooBar.s3);
   }
}

请问您能解释一下这段代码吗?dict[1] = d1; dict[1].FooBar = "Aniket"; 我理解中 dic[1].FooBar = Aniket 是字典的键,但在这种情况下 FooBar 代表什么意思呢? - vladimir
@vladimir 在这种情况下,.FooBar 表示它可以是任何东西。你可以使用相同的代码将 .FooBar 替换为 .vladimir,它仍然可以工作。我已经在运行时动态地在 dict[1](指向 d1)中创建了一个名为 FooBar 的属性。 - Aniket Inge
我们能否将DICT初始化为全局变量,例如 <string,dynamic> {"Sweden",currentRate = 9.95},{"Sweden",currency = "SEK"} - Ravi Parekh
1
这是一个很棒的解决方案。有点像把C#转化成了JavaScript。谢谢。 - BoundForGlory

7

使用描述适当的关键字段和适当的值字段,并使用这些类型的字典。

var dictionary = new Dictionary<TheKeyType, TheValuesType>();

注意:如果您有多个值充当键,则应定义一个类来封装这些值,并提供适当的GetHashCode和Equals覆盖,以便字典可以识别它们的相等性。
除此之外,您可以利用元组,但是您要限制此模式,因为元组不具备自我描述性。
var dictionary = new Dictionary<Tuple<Key1Type, Key2Type, Etc>, Tuple<Value1Type, Value2Type, Etc>>();

4

不要使用元组,虽然这是一种完全有效的解决方案,但我建议创建自己的类作为键和/或值。

你会意识到元组会使代码难以阅读。


有一个前提条件,那就是他必须手动实现Equals()和GetHashCode()。 - System Down
@SystemDown:感谢您指出这一点。我们必须权衡利弊来做出决定。 - Luis Filipe
4
只有当自定义类是键时才是正确的;如果它是值,则不需要。 - Servy
1
请创建您自己的类,不要使用元组,因为它极其难以维护。 - goamn
现在有了命名元组,我的回答可以被认为已经过时了。 - Luis Filipe

1
使用元组作为键。
var d = new Dictionary<Tuple<string,string,bool,int>,any-data-typs>();

4
我建议使用其中一种类型作为键,而将Tuple<...>作为值。 - Lukasz M
谢谢,这就是我想要的。我会像这样使用它: var d = new Dictionary<string,Tuple<string,string,bool,int,any-data-typs>>(); - diwatu
1
@LukaszM - 我的理解是他想要一个复合键。 - System Down
@Giswin - 如果你想要一个复合键,那么这个方法可以实现。但是由于元组本身并没有自我描述的特性,所以可能会有些麻烦。 - System Down
我明白了。我想他只是想要一个将超过两个值关联在一起的集合。无论如何,Tuple类都可以在这两种情况下使用 :)。 - Lukasz M
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接