ZetCode

C# KeyValuePair 教程

最后修改于 2025 年 5 月 13 日

C# 中的 KeyValuePair 结构体是一个表示键值对的基础数据结构。它通常与字典和其他集合类型一起使用,用于存储成对的元素。本教程将深入探讨 KeyValuePair。

KeyValuePair 是一个定义在 System.Collections.Generic 命名空间下的泛型结构体。它封装了两个相关的元素:一个键(key)和一个值(value)。

这个结构体主要用于处理字典,但也可以用在其他需要将两个值关联在一起的场景中。它是一个轻量级、不可变的结构体,提供了高效的存储。

当需要遍历字典条目或从方法返回单个键值对时,KeyValuePair 特别有用。

基础 KeyValuePair 示例

此示例演示了 KeyValuePair 的最基本用法,包括创建实例和访问其属性。

Program.cs
KeyValuePair<string, int> product1 = new ("Apples", 50);
var product2 = new KeyValuePair<string, int>("Oranges", 30);

Console.WriteLine($"Product: {product1.Key}, Quantity: {product1.Value}");
Console.WriteLine($"Product: {product2.Key}, Quantity: {product2.Value}");

DisplayKeyValuePair(product1);

void DisplayKeyValuePair(KeyValuePair<string, int> pair)
{
    Console.WriteLine($"In method - Key: {pair.Key}, Value: {pair.Value}");
}

此代码展示了如何创建 KeyValuePair 实例并访问其 Key 和 Value 属性。它还演示了如何将 KeyValuePair 传递给方法。

KeyValuePair<string, int> product1 = new ("Apples", 50);

创建一个键为字符串 "Apples"、值为整数 50 的 KeyValuePair。泛型参数指定了键和值的类型。

var product2 = new KeyValuePair<string, int>("Oranges", 30);

使用 var 关键字进行隐式类型推断。编译器会从赋值的右侧推断出类型。

Console.WriteLine($"Product: {product1.Key}, Quantity: {product1.Value}");

访问 KeyValuePair 实例的 Key 和 Value 属性。这些属性是只读的。

KeyValuePair 与字典

在处理字典时,最常遇到 KeyValuePair。此示例展示了在遍历字典条目时如何使用它。

Program.cs
Dictionary<string, int> inventory = new()
{
    {"Apples", 50},
    {"Oranges", 30},
    {"Bananas", 45},
    {"Grapes", 25}
};

Console.WriteLine("Inventory Contents:");
foreach (KeyValuePair<string, int> item in inventory)
{
    Console.WriteLine($"{item.Key}: {item.Value} units");
}

KeyValuePair<string, int> bananaItem = inventory.FirstOrDefault(
    x => x.Key == "Bananas");
if (bananaItem.Key != null)
{
    Console.WriteLine($"\nFound: {bananaItem.Key} - {bananaItem.Value}");
}

此示例演示了将 KeyValuePair 与字典一起使用,包括迭代和搜索操作。

foreach (KeyValuePair<string, int> item in inventory)

当遍历字典时,每个元素都是一个包含该条目键和值的 KeyValuePair。这是 KeyValuePair 的主要用例。

KeyValuePair<string, int> bananaItem = inventory.FirstOrDefault(
    x => x.Key == "Bananas");

使用 LINQ 的 FirstOrDefault 在字典中查找特定的 KeyValuePair。请注意,我们通过检查 Key 是否为 null 来判断是否找到了该项。

方法返回中的 KeyValuePair

当需要从一个方法返回两个相关的值时,KeyValuePair 可以作为一种有用的返回类型。此示例展示了这种模式。

Program.cs
int[] numbers = { 12, 45, 7, 32, 19, 3, 56 };
var minMax = FindMinMax(numbers);

Console.WriteLine($"Minimum: {minMax.Key}, Maximum: {minMax.Value}");

var result = TryParseNumber("42");
if (result.Key)
{
    Console.WriteLine($"Parsed successfully: {result.Value}");
}

KeyValuePair<int, int> FindMinMax(int[] numbers)
{
    if (numbers == null || numbers.Length == 0)
    {
        throw new ArgumentException("Array cannot be empty");
    }

    int min = numbers[0];
    int max = numbers[0];

    foreach (int num in numbers)
    {
        if (num < min) min = num;
        if (num > max) max = num;
    }

    return new KeyValuePair<int, int>(min, max);
}

KeyValuePair<bool, int> TryParseNumber(string input)
{
    bool success = int.TryParse(input, out int result);
    return new KeyValuePair<bool, int>(success, result);
}

此代码演示了将 KeyValuePair 用作返回类型的两种常见模式:返回相关值(最小值/最大值)和实现 TryParse 模式。

KeyValuePair<int, int> FindMinMax(int[] numbers)

方法返回两个相关的整数(最小值和最大值),并将它们打包在一个 KeyValuePair 中。在某些情况下,这比使用 out 参数更清晰。

KeyValuePair<bool, int> TryParseNumber(string input)

使用 KeyValuePair 实现 TryParse 模式,同时返回一个成功标志和解析后的值。这类似于 int.TryParse 使用 out 参数的工作方式。

高级 KeyValuePair 用法

此示例展示了更高级的场景,包括解构、LINQ 操作以及使用 KeyValuePair 进行自定义比较。

Program.cs
Dictionary<string, decimal> productPrices = new()
{
    {"Laptop", 999.99m},
    {"Phone", 699.99m},
    {"Tablet", 349.99m},
    {"Monitor", 249.99m}
};

foreach (var (product, price) in productPrices)
{
    Console.WriteLine($"{product} costs {price:C}");
}

var expensiveItems = productPrices
    .Where(kvp => kvp.Value > 500m)
    .OrderByDescending(kvp => kvp.Value);

Console.WriteLine("\nExpensive Items:");
foreach (var item in expensiveItems)
{
    Console.WriteLine($"{item.Key}: {item.Value:C}");
}

KeyValuePair<string, decimal> mostExpensive = productPrices
    .OrderByDescending(kvp => kvp.Value)
    .First();

Console.WriteLine($"\nMost expensive: {mostExpensive.Key} at {mostExpensive.Value:C}");

此示例演示了现代 C# 的特性,如解构、LINQ 操作以及使用 KeyValuePair 进行自定义排序。

foreach (var (product, price) in productPrices)

使用解构语法将 KeyValuePair 分解为独立的变量。这在 C# 7.0 及更高版本中可用,可以使代码更简洁。

.Where(kvp => kvp.Value > 500m)
.OrderByDescending(kvp => kvp.Value);

展示了基于字典中 KeyValuePair 的 Value 属性进行过滤和排序的 LINQ 操作。

KeyValuePair<string, decimal> mostExpensive = productPrices
    .OrderByDescending(kvp => kvp.Value)
    .First();

通过按值排序并取第一项来找到最贵的物品。演示了 KeyValuePair 如何用于自定义比较操作。

来源

微软 KeyValuePair 文档

KeyValuePair 是一个多功能的结构体,它提供了一种简洁的方式来处理 C# 中的成对数据。它在与字典一起使用时特别有用,但正如这些示例所示,它也具有更广泛的应用。

作者

我的名字是 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。至今,我已撰写了超过 1400 篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

列出所有 C# 教程