元组

析构元组

将 var 关键字放在括号外,可使用 var 关键字,以便 C# 推断每个变量的类型。 
var (name, address, city, zip) = contact.GetAddressInfo();

从 C# 10 开始,可在析构中混合使用变量声明和赋值。

public static void Main()
{
    string city = "Raleigh";
    int population = 458880;

    (city, population, double area) = QueryCityData("New York City");

    // Do something with the data.
}

 

析构用户定义类型

除了 record 和 DictionaryEntry 类型,C# 不提供析构非元组类型的内置支持。 但是,用户作为类、结构或接口的创建者,可通过实现一个或多个 Deconstruct方法来析构该类型的实例。 该方法返回 void,且要析构的每个值由方法签名中的 out 参数指示

public void Deconstruct(out string fname, out string mname, out string lname)

 DictionaryEntry类型提供 Deconstruct 方法。

Dictionary<string, int> snapshotCommitMap = new(StringComparer.OrdinalIgnoreCase)
{
    ["https://github.com/dotnet/docs"] = 16_465,
    ["https://github.com/dotnet/runtime"] = 114_223,
    ["https://github.com/dotnet/installer"] = 22_436,
    ["https://github.com/dotnet/roslyn"] = 79_484,
    ["https://github.com/dotnet/aspnetcore"] = 48_386
};

foreach (var (repo, commitCount) in snapshotCommitMap)
{
    Console.WriteLine(
        $"The {repo} repository had {commitCount:N0} commits as of November 10th, 2021.");
}

 

使用扩展方法析构用户定义的类型

如果不是类的创建者,仍可通过实现一个或多个 Deconstruct扩展方法来析构该类型的对象,以返回所需值。

public static void Deconstruct(this PropertyInfo p, out bool isStatic,
                                   out bool isReadOnly, out bool isIndexed,
                                   out Type propertyType)

PropertyInfo prop = dateType.GetProperty("Now");
var (isStatic, isRO, isIndexed, propType) = prop;

推断元组元素名称

元组元素的名称可通过在初始化元组时使用的变量进行推断:

int count = 5;
string label = "Colors used in the map";
var pair = (count, label); // element names are "count" and "label"

 

支持 == 和 !=

两个元组具有相同数量的元素,且对于每个元组位置,可以使用 == 和 != 运算符对左右侧元组操作数中的相应元素进行比较

(int a, byte b) left = (5, 10);
(long a, int b) right = (5, 10);
Console.WriteLine(left == right);  // output: True
Console.WriteLine(left != right);  // output: False

var t1 = (A: 5, B: 10);
var t2 = (B: 5, A: 10);
Console.WriteLine(t1 == t2);  // output: True
Console.WriteLine(t1 != t2);  // output: False

== 和 != 操作不会考虑元组字段名称。

== 和 != 运算符将以短路方式对元组进行比较。  

  

在匿名类型和元组类型之间进行选择

主要区别
“属性”访问修饰符类型自定义成员名称析构支持表达式树支持
匿名类型 internal class ✔️ ✔️
Tuple public class ✔️
ValueTuple public struct ✔️ ✔️

在元组和匿名类型之间进行选择时,需要考虑几个因素。 一般来说,如果不使用表达式树,并且你熟悉元组语法,请选择 ValueTuple,因为它们提供可灵活命名属性的值类型。 如果使用表达式树并且想要命名属性,请选择匿名类型。

 ValueTuple 类型是可变的,而 Tuple 是只读的。  

 

Tips

使用元组来交换值,因此无需使用临时变量按顺序交换参数即可使用元组的重构

int[] c = { 0, 1 };

(c[1], c[0]) = (c[0], c[1]);

Console.WriteLine(c[0] + " " + c[1]); // 1 0

 

posted @ 2020-08-03 19:30  yetsen  阅读(117)  评论(0编辑  收藏  举报