C# - Dictionary<TKey, TValue>

Dictionary<TKey, TValue> 是一个通用字典集合,它以没有特定顺序存储键值对。 (跟SortedList比它不排序)

Dictionary特征

  • Dictionary<TKey, TValue> 存储键值对。
  • 属于 System.Collections.Generic 命名空间。
  • 实现 IDictionary<TKey, TValue> 接口。
  • 键必须是唯一的,不能为空。
  • 值可以为空或重复。
  • 可以通过在索引器中传递关联的键来访问值,例如 我的字典[键]
  • 元素存储为 KeyValuePair<TKey, TValue> 对象。
  • 内部使用hash算法

创建Dictionary

您可以通过传递符合要求的键值对来创建 Dictionary<TKey, TValue> 对象。 以下示例显示如何创建字典并添加键值对。

static void Main(string[] args)
{
    var dict0 = new Dictionary<int, string>()
    {
        [1] = "a",
        [2] = "b"
    };

    // C#6.0 之后 提供的 Index Initializers 索引初始化器
    var dict1 = new Dictionary<string, string>()
    {
        ["xm"] = "厦门",
        ["bj"] = "北京",
        ["sh"] = "上海",
    };

    var dict2 = new Dictionary<string, string>()
    {
        { "xm" ,"厦门"},
        { "bj" ,"北京"},
        { "sh" ,"上海" },
    };

    var dict3 = new Dictionary<string, string>();
    dict3.Add("xm", "厦门");
    dict3.Add("bj", "北京");
    dict3.Add("sh", "上海");

    foreach (var kvp in dict3)
        Console.WriteLine("Key: {0}, Value: {1}", kvp.Key, kvp.Value);

    //Key: xm, Value: 厦门
    //Key: bj, Value: 北京
    //Key: sh, Value: 上海
}

在上面的例子中,dict0 是一个 Dictionary<int, string> 类型的字典,所以它可以存储 int 键和字符串值。 同样的,dict1,dict2,dict3是一个 Dictionary<string, string> 类型的字典,所以它可以存储字符串键和字符串值。 字典不能包含重复键或空键,而值可以是重复键或空键。 键必须是唯一的,否则会抛出运行时异常。

访问 Dictionary

我们可以使用索引器访问字典。 通过一个Key来获取相关联的值。 也还可以使用 ElementAt() 方法从指定的索引中获取 KeyValuePair。

static void Main(string[] args)
{
    var dict1 = new Dictionary<string, string>()
    {
        ["xm"] = "厦门",
        ["bj"] = "北京",
        ["sh"] = "上海",
    };

    Console.WriteLine(dict1["xm"]);  //输出 厦门
    Console.WriteLine(dict1["bj"]);  //输出 北京
    //Console.WriteLine(dict1["malema"]); // System.Collections.Generic.KeyNotFoundException

    if (dict1.ContainsKey(".net"))
    {
        //没有这个key不会输出
        Console.WriteLine(dict1[".net"]);
    }

    //use TryGetValue() to get a value of unknown key
    string result;

    if (dict1.TryGetValue("xm", out result))
    {
        Console.WriteLine(result);//输出 厦门
    }

    for (int i = 0; i < dict1.Count; i++)
    {
        Console.WriteLine($"Key: {dict1.ElementAt(i).Key}, Value: { dict1.ElementAt(i).Value}");
    }
    //for循环输出下面三个
    //Key: xm, Value: 厦门
    //Key: bj, Value: 北京
    //Key: sh, Value: 上海
}

更新 Dictionary

通过索引器来更新值,如果这个key 不存在的话则会添加一个新的。 (注意 如果用Add来添加的话要先判断有没有存,不然会出错,通过这种方式来添加的话则不需要判断)

static void Main(string[] args)
{
    var dict1 = new Dictionary<string, string>()
    {
        ["xm"] = "厦门",
        ["bj"] = "北京",
        ["sh"] = "上海",
    };

    dict1["cn"] = "中国";
    dict1["xm"] = "厦门2021";

    Console.WriteLine(string.Join(",", dict1.Keys));
    // xm,bj,sh,cn
}

从 Dictionary 里删除元素

static void Main(string[] args)
{
    var dict1 = new Dictionary<string, string>()
    {
        ["xm"] = "厦门",
        ["bj"] = "北京",
        ["sh"] = "上海",
    };

    dict1.Remove("xm");
    dict1.Remove("xm2"); //.net5.0 没有这个key也不会出错

    Console.WriteLine(string.Join(",", dict1.Keys));
    // bj,sh

    dict1.Clear(); //清掉所有
    Console.WriteLine(string.Join(",", dict1.Keys));
    //没东西了
}

把条件判断转化成 查表

如下的代码。我们需要把code转成名字, 我们可以用if else 或者 switch来写这个代码。 但是更方便的则是我们创建一个Dictionary然后直接查表。

 static void Main(string[] args)
        {
            var name = GetNameByCode("xm");

            var dict1 = new Dictionary<string, string>()
            {
                ["xm"] = "厦门",
                ["bj"] = "北京",
                ["sh"] = "上海",
            };

            var name2 = dict1["xm"];

        }

        private static string GetNameByCode(string code)
        {

            switch (code)
            {
                case "xm":
                    return "厦门";

                case "bj":
                    return "北京";

                case "sh":
                    return "上海";
            }
            throw new ArgumentOutOfRangeException("找不到这个Key");
        }

其它复杂的操作也是可以类似上面转成查表的。只是把value部分变成 Action<> 或者 Func<>

Hashtable

这个类是Dictionary类型的非泛型实现。有了Dictionary后我们基本上不用它了。

查看源码。 放在了 System.Private.CoreLib 这个下面

参考 https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2?view=net-5.0

上一篇:C# SortedList
下一篇:C# 堆栈 Stack
最近更新的
...