C#语法手册

元组语法


元组 ValueTuple 的基本语法。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static CSGDemoCSG011.Demo1;

namespace CSGDemoCSG011
{
    //https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/builtin-types/value-tuples
    //https://docs.microsoft.com/zh-cn/dotnet/csharp/deconstruct


    //#csg011-01
    //元组在 C# 7.0 及更高版本中可用
    //它提供了简洁的语法,用于将多个数据元素分组成一个轻型数据结构。
    //元组的类型为 System.ValueTuple,并且 ValueTuple 为值类型


    public class Demo1
    {
        public Demo1()
        {
            //#csg011-02
            //元组的声明,使用默认字段名称
            (double, int) t1 = (4.5, 3);
            Console.WriteLine($"Tuple with elements {t1.Item1} and {t1.Item2}.");

            //#csg011-03
            //元组的声明,使用自定义字段名称
            (double Sum, int Count) t2 = (4.5, 3);
            Console.WriteLine($"Sum of {t2.Count} elements is {t2.Sum}.");
        }



        //#csg011-04
        //在方法中使用元组
        (int min, int max) FindMinMax(int[] input)
        {
            if (input is null || input.Length == 0)
            {
                throw new ArgumentException("null or empty array.");
            }

            var min = int.MaxValue;
            var max = int.MinValue;
            foreach (var i in input)
            {
                if (i < min)
                {
                    min = i;
                }
                if (i > max)
                {
                    max = i;
                }
            }
            return (min, max);
        }


        public void Method1()
        {
            //#csg011-05
            //元组的析构,将元组中的元素分配给不同的变量
            //
            var (minValue, maxValue) = this.FindMinMax(new[] { 1, 2, 3, 4, 5, 6, 7 });
            Console.WriteLine("min value:" + minValue);
            Console.WriteLine("max value:" + maxValue);

        }



        public void Method2()
        {
            //#csg011-06
            //弃元析构
            //本例中如果你只需要maxValue,你可以通过下面的语法只获取maxValue
            var (_, maxValue) = this.FindMinMax(new[] { 1, 2, 3, 4, 5, 6, 7 });
            Console.WriteLine("max value:" + maxValue);
        }


        //#csg011-07
        //析构用于定义类型
        //除了 record 和 DictionaryEntry 类型,C# 不提供析构非元组类型的内置支持。
        //不过用户可以为类,结构,接口实现Deconstruct方法来实现这些类型的析构
        public class Person
        {

            public string FirstName { get; set; }
            public string LastName { get; set; }
            public string City { get; set; }

            public void Deconstruct(out string fname, out string lname, out string city)
            {
                fname = FirstName;
                lname = LastName;
                city = City;
            }

        }

        //#csg011-07
        //自定义析构的使用
        public void Method3()
        {
            var person = new Person();
            var (firstName, lastName, city) = person;
            Console.WriteLine(firstName);
            Console.WriteLine(lastName);
            Console.WriteLine(city);

        }


        //#csg011-09
        //元组相等操作
        //从 C# 7.3 开始,元组类型支持 == 和 != 运算符。
        public void Method4()
        {
            (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
        }



        //#csg011-10
        //ValueTuple,Tuple 的区别
        //System.ValueTuple 类型支持的 C# 元组不同于 System.Tuple 类型表示的元组。
        //区别如下:
        //ValueTuple 类型是值类型。 Tuple 类型是引用类型。
        //ValueTuple 类型是可变的。 Tuple 类型是不可变的。
        //ValueTuple 类型的数据成员是字段。 Tuple 类型的数据成员是属性。



        //#csg011-11
        //ValueTuple,Tuple 以及匿名类型的主要区别

        //           访问修饰符    类型    自定义成员名称   析构支持   表达式树支持
        //匿名类型    internal     class      ✔️            ❌          ✔️
        //Tuple      public       class     ❌            ❌          ✔️
        //ValueTuple public       struct     ✔️            ✔️	       ❌

    }



    public static class Extensions
    {
        //#csg011-12
        //使用扩展方法对类型添加析构支持
        public static void Deconstruct(this Person person, out string fname, out string lname)
        {
            fname = person.FirstName;
            lname = person.LastName;
        }

    }


}