C# Dictionary初始化的详解

发布时间:2023-05-23

一、基础认识

C#中的Dictionary是一种键值对存储的数据类型,可以根据键(Key)访问对应的值(Value),它是.NET Framework中的常用类之一。创建Dictionary的方式包括使用默认构造函数,使用带有容量参数的构造函数,以及从其他Dictionary或键值对数组中填充Dictionary。 下面是使用默认构造函数创建Dictionary的示例代码:

Dictionary<string, int> dict = new Dictionary<string, int>();

以上代码创建了一个空的Dictionary,可以使用Add方法添加新的键值对,也可以通过索引器访问Dictionary中的特定键值对。使用Add方法添加新键值对:

dict.Add("Apple", 1);
dict.Add("Banana", 2);
dict.Add("Orange", 3);

使用索引器访问Dictionary中的键值对:

int count = dict["Apple"];

如果键值对不存在,则会抛出KeyNotFoundException异常。还可以使用TryGetValue方法避免这种情况:

int count;
if(!dict.TryGetValue("onion", out count))
{
    Console.WriteLine("No such key exists in the dictionary.");
}

二、容量和性能优化

使用带有容量参数的构造函数,可以在创建Dictionary时指定预计容量,这会为存储数据提供更好的性能和增加容量的灵活性。当Dictionary的元素数量超过容量时,系统会自动重新分配更大的内存空间,这可能会导致性能下降。因此,预计Dictionary中存储的元素数量并指定初始容量是一种容量和性能优化的方式。 以下是使用带有容量参数的构造函数创建Dictionary的示例代码:

Dictionary<string, int> dict = new Dictionary<string, int>(100);

三、从其他数据类型填充Dictionary

从其他Dictionary、数组或列表中填充Dictionary是常用的操作,下面是从另一个Dictionary中填充Dictionary的示例代码:

Dictionary<string, int> sourceDict = new Dictionary<string, int>
{
    { "Apple", 1 },
    { "Banana", 2 },
    { "Orange", 3 }
};
Dictionary<string, int> targetDict = new Dictionary<string, int>(sourceDict);

以上代码从sourceDict中复制键值对到targetDict,targetDict现在包含与sourceDict相同的键值对。也可以使用ToDictionary方法从数组或列表中创建Dictionary,下面是从数组中创建Dictionary的示例代码:

string[] fruits = { "Apple", "Banana", "Orange" };
int[] counts = { 1, 2, 3 };
Dictionary<string, int> dict = fruits
    .Select((fruit, index) => new { fruit, count = counts[index] })
    .ToDictionary(item => item.fruit, item => item.count);

以上代码使用Select方法将fruits和counts数组组合成一个元素类型为{string, int}的数组,然后使用ToDictionary方法将该数组转换为Dictionary。这种方式可以从任何数组或列表中创建Dictionary。

四、使用枚举器来访问Dictionary中的元素

遍历Dictionary中的键值对通常需要使用枚举器。这里介绍两种使用枚举器的方式:使用foreach语句和使用LINQ查询。 使用foreach语句遍历Dictionary中的键值对:

Dictionary<string, int> dict = new Dictionary<string, int>
{
    { "Apple", 1 },
    { "Banana", 2 },
    { "Orange", 3 }
};
foreach(KeyValuePair<string, int> pair in dict)
{
    Console.WriteLine("{0} = {1}", pair.Key, pair.Value);
}

以上代码使用foreach语句遍历Dictionary中的键值对,并输出键和值。KeyValuePair<TKey, TValue> 是一个由键和值组成的结构体,它包含Key和Value属性。 使用LINQ查询遍历Dictionary中的键值对:

Dictionary<string, int> dict = new Dictionary<string, int>
{
    { "Apple", 1 },
    { "Banana", 2 },
    { "Orange", 3 }
};
var pairs = dict.Select(pair => string.Format("{0} = {1}", pair.Key, pair.Value));
Console.WriteLine(string.Join(", ", pairs));

以上代码使用LINQ查询遍历Dictionary中的键值对,并将键值对输出为字符串。

五、使用EqualityComparer自定义Dictionary的键类型

默认情况下,Dictionary中的键类型为Object,如果键类型不是基元类型或字符串等.NET Framework提供的一些常用类型,则需要自定义EqualityComparer。EqualityComparer是一个用于比较两个对象是否相等的类型,需要实现GetHashCode和Equals方法,以下是实现自定义EqualityComparer的示例代码:

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}
class PersonEqualityComparer : IEqualityComparer<Person>
{
    public bool Equals(Person x, Person y)
    {
        return x.Name == y.Name && x.Age == y.Age;
    }
    public int GetHashCode(Person obj)
    {
        return obj.Name.GetHashCode() ^ obj.Age;
    }
}
Dictionary<Person, int> dict = new Dictionary<Person, int>(new PersonEqualityComparer())
{
    { new Person { Name = "Alice", Age = 20 }, 1 },
    { new Person { Name = "Bob", Age = 25 }, 2 }
};
int count = dict[new Person { Name = "Alice", Age = 20 }];

以上代码使用自定义EqualityComparer,将Person类型用作Dictionary的键类型,并添加了两个Person键值对。注意,Person类需要实现GetHashCode和Equals方法才能与自定义EqualityComparer一起使用。

六、总结

本文从基础使用、容量和性能优化、从其他数据类型填充、使用枚举器访问、自定义EqualityComparer等多个方面对C#中的Dictionary初始化进行了详细的介绍和讲解,希望读者对于该数据类型有更加深入的了解和掌握。