KeyValuePair<>结构中Deconstruct方法的目的是什么?

3
我是一位翻译助手,以下是您需要翻译的内容:

我在查看 System.Runtime, Version=4.2.1.0 中的 System.Collections.Generic.KeyValuePair<TKey, TValue> 结构,并且这个方法引起了我的注意。

这是它的签名:

public void Deconstruct(out TKey key, out TValue value);

除了简单地转发Key和Value属性之外,它是否包含任何逻辑?为什么有人会喜欢它而不是使用属性getter呢?


1
这是针对C# 7中引入的解构语法的。请参阅https://learn.microsoft.com/en-us/dotnet/csharp/deconstruct。该方法不打算直接调用,而是通过编写`var (key, value) = SomeMethodReturningAKeyValuePair()`来隐式调用。 - undefined
如果我说错了,请纠正我:对于“为什么更喜欢使用解构赋值而不是属性获取器”的部分,我能想到的原因是属性获取器是一个方法,因此每次访问时都会运行,可能导致每次都得到不同的值。但一旦在某个时间点进行解构赋值,那个时间点的值就被保留下来,可以在以后使用,而此时“最新”的属性值可能已经发生了变化。 - undefined
@Nico - 在这种情况下,我们仍然可以手动跟踪变量的值,例如 var x = object.thing。只要它是一个值类型或不可变的(例如字符串),值就不应该改变。然而,如果你解构一个是对象的属性,那么该值就可以被更新。这也是 JavaScript 中的副作用。 - undefined
2个回答

12

拆构是C# 7中引入的一个特性,主要用于值元组,在单个操作中“拆开元组中的所有项”。语法已经被泛化,以允许它用于其他类型。通过定义Deconstruct方法,您可以使用简洁的拆解语法将内部值分配给单独的变量:

var kvp = new KeyValuePair<int, string>(10, "John");
var (id, name) = kvp;

甚至可以通过定义一个具有out参数和void返回类型的Deconstruct方法来对自定义用户类型进行解构,就像你的示例中一样。请参见解构用户定义类型

编辑:虽然C#7解构语法在.NET Framework和.NET Core中都得到支持,但KeyValuePair<TKey,TValue>.Deconstruct方法目前仅受到.NET Core 2.0及更高版本的支持。请参阅上一个链接中的“适用于”部分。


2

Deconstruction被用于在C#中实现模式匹配(Scala中的FP概念),可以将键和值分开。同样,也可以使用switch表达式。

KeyValuePairTest(new KeyValuePair<string, string>("Hello", "World"));
KeyValuePairTest(new KeyValuePair<int, int>(5,7));

private static void KeyValuePairTest<TKey, TValue>(KeyValuePair<TKey,TValue> keyValuePair)
{
    var (k, v) = keyValuePair;
    Console.WriteLine($"Key {k}, value is {v}");

    switch (keyValuePair)
    {
        case KeyValuePair<string, string> t:
            Console.WriteLine(t.Key + " " + t.Value);break;
        case KeyValuePair<int, int> t:
            Console.WriteLine(t.Key + t.Value); break;
    }
}

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