• C# 元组和弃元的用法


    C# 元组和弃元的用法

     
    元组

    元组功能在 C# 7.0 及更高版本中可用,它提供了简洁的语法,用于将多个数据元素分组成一个轻型数据结构。C# 为用于说明设计意图的类和结构提供了丰富的语法。 但是,这种丰富的语法有时会需要额外的工作,但益处却很少。 你可能经常编写需要包含多个数据元素的简单结构的方法。 为了支持这些方案,已将元组添加到了 C#。了解更多点击元组。下面的示例演示了如何声明元组变量、对它进行初始化并访问其数据成员:

    复制代码
    (double, int) t1 = (4.5, 3);
    Console.WriteLine($"Tuple with elements {t1.Item1} and {t1.Item2}.");
    // Output:
    // Tuple with elements 4.5 and 3.
    
    (double Sum, int Count) t2 = (4.5, 3);
    Console.WriteLine($"Sum of {t2.Count} elements is {t2.Sum}.");
    // Output:
    // Sum of 3 elements is 4.5.
    
    (double Sum, int Count)  = (4.5, 3);
    Console.WriteLine($"Tuple with elements {Sum} and {Count}.");
    // Output:
    // Tuple with elements 4.5 and 3.
    复制代码

    如前面的示例所示,若要定义元组类型,需要指定其所有数据成员的类型,或者,可以指定字段名称。 虽然不能在元组类型中定义方法,但可以使用 .NET 提供的方法,如下面的示例所示:

    复制代码
    (double, int) t = (4.5, 3);
    Console.WriteLine(t.ToString());
    Console.WriteLine($"Hash code of {t} is {t.GetHashCode()}.");
    // Output:
    // (4.5, 3)
    // Hash code of (4.5, 3) is 718460086.
    复制代码

    从 C# 7.3 开始,元组类型支持相等运算符== 和 !=。 有关详细信息,请参阅元组相等部分。

    元组类型是值类型;元组元素是公共字段。 这使得元组为可变的值类型。

    可以使用任意数量的元素定义元组:

    复制代码
    var t = 
    (1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
    11, 12, 13, 14, 15, 16, 17, 18,
    19, 20, 21, 22, 23, 24, 25, 26);
    Console.WriteLine(t.Item26);  // output: 26
    复制代码

    元组的用例

    元组最常见的用例之一是作为方法返回类型。 也就是说,你可以将方法结果分组为元组返回类型,而不是定义 out 方法参数,如以下示例所示:

    复制代码
    var xs = new[] { 4, 7, 9 };
    var limits = FindMinMax(xs);
    Console.WriteLine($"Limits of [{string.Join(" ", xs)}] are {limits.min} and {limits.max}");
    // Output:
    // Limits of [4 7 9] are 4 and 9
    
    var ys = new[] { -9, 0, 67, 100 };
    var (minimum, maximum) = FindMinMax(ys);
    Console.WriteLine($"Limits of [{string.Join(" ", ys)}] are {minimum} and {maximum}");
    // Output:
    // Limits of [-9 0 67 100] are -9 and 100
    
    (int min, int max) FindMinMax(int[] input)
    {
        if (input is null || input.Length == 0)
        {
            throw new ArgumentException("Cannot find minimum and maximum of a 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);
    }
    复制代码

    弃元

    从 C# 7.0 开始,C# 支持弃元,这是一种在应用程序代码中人为取消使用的占位符变量。 弃元相当于未赋值的变量;它们没有值。 弃元将意图传达给编译器和其他读取代码的文件:你打算忽略表达式的结果。 你可能需要忽略表达式的结果、元组表达式的一个或多个成员、方法的 out 参数或模式匹配表达式的目标。了解更多点击查看

    弃元使代码意图更加明确。 放弃表示代码永远不会使用变量。 它们可以增强其可读性和可维护性。

    通过将下划线 (_) 赋给一个变量作为其变量名,指示该变量为一个占位符变量。 例如,以下方法调用返回一个元组,其中第一个值和第二个值为弃元。 area 是以前声明的变量,设置为由 GetCityInformation 返回的第三个组件:

    (_, _, area) = city.GetCityInformation(cityName);

    从 C# 9.0 开始,可以使用弃元指定 Lambda 表达式中不使用的输入参数。 有关详细信息,请参阅 Lambda 表达式一文中的 Lambda 表达式的输入参数一节。

    当 _ 是有效弃元时,尝试检索其值或在赋值操作中使用它时会生成编译器错误 CS0301:“当前上下文中不存在名称 "_"”。 出现此错误是因为 _ 未赋值,甚至可能未分配存储位置。 如果它是一个实际变量,则不能像之前的示例那样对多个值使用弃元。

    元组和对象析构

    如果应用程序代码使用某些元组元素,但忽略其他元素,这时使用弃元来处理元组就会很有用。 例如,以下 QueryCityDataForYears 方法返回一个元组,包含城市名称、城市面积、一个年份、该年份的城市人口、另一个年份及该年份的城市人口。 该示例显示了两个年份之间人口的变化。 对于元组提供的数据,我们不关注城市面积,并在一开始就知道城市名称和两个日期。 因此,我们只关注存储在元组中的两个人口数量值,可将其余值作为占位符处理。

    复制代码
    var (_, _, _, pop1, _, pop2) = QueryCityDataForYears("New York City", 1960, 2010);
    
    Console.WriteLine($"Population change, 1960 to 2010: {pop2 - pop1:N0}");
    
    static (string, double, int, int, int, int) QueryCityDataForYears(string name, int year1, int year2)
    {
        int population1 = 0, population2 = 0;
        double area = 0;
    
        if (name == "New York City")
        {
            area = 468.48;
            if (year1 == 1960)
            {
                population1 = 7781984;
            }
            if (year2 == 2010)
            {
                population2 = 8175133;
            }
            return (name, area, year1, population1, year2, population2);
        }
    
        return ("", 0, 0, 0, 0, 0);
    }
    // The example displays the following output:
    //      Population change, 1960 to 2010: 393,149
    复制代码

    类、结构或接口的 Deconstruct 方法还允许从对象中检索和析构一组特定的数据。 如果想只使用析构值的一个子集,可使用弃元。 以下示例将 Person 对象析构为四个字符串(名字、姓氏、城市和省/市/自治区),但舍弃姓氏和省/市/自治区。

    复制代码
    using System;
    
    namespace Discards
    {
        public class Person
        {
            public string FirstName { get; set; }
            public string MiddleName { get; set; }
            public string LastName { get; set; }
            public string City { get; set; }
            public string State { get; set; }
    
            public Person(string fname, string mname, string lname,
                          string cityName, string stateName)
            {
                FirstName = fname;
                MiddleName = mname;
                LastName = lname;
                City = cityName;
                State = stateName;
            }
    
            // Return the first and last name.
            public void Deconstruct(out string fname, out string lname)
            {
                fname = FirstName;
                lname = LastName;
            }
    
            public void Deconstruct(out string fname, out string mname, out string lname)
            {
                fname = FirstName;
                mname = MiddleName;
                lname = LastName;
            }
    
            public void Deconstruct(out string fname, out string lname,
                                    out string city, out string state)
            {
                fname = FirstName;
                lname = LastName;
                city = City;
                state = State;
            }
        }
        class Example
        {
            public static void Main()
            {
                var p = new Person("John", "Quincy", "Adams", "Boston", "MA");
    
                // Deconstruct the person object.
                var (fName, _, city, _) = p;
                Console.WriteLine($"Hello {fName} of {city}!");
                // The example displays the following output:
                //      Hello John of Boston!
            }
        }
    }
    复制代码

    弃元模式可通过 switch 表达式用于模式匹配。 每个表达式(包括 null)都始终匹配弃元模式。

    以下示例定义了一个 ProvidesFormatInfo 方法,它使用 switch 表达式来确定对象是否提供 IFormatProvider 实现并测试对象是否为 null。 它还使用占位符模式来处理任何其他类型的非 null 对象。

    复制代码
    object?[] objects = { CultureInfo.CurrentCulture,
                       CultureInfo.CurrentCulture.DateTimeFormat,
                       CultureInfo.CurrentCulture.NumberFormat,
                       new ArgumentException(), null };
    foreach (var obj in objects)
        ProvidesFormatInfo(obj);
    
    static void ProvidesFormatInfo(object? obj) =>
        Console.WriteLine(obj switch
        {
            IFormatProvider fmt => $"{fmt.GetType()} object",
            null => "A null object reference: Its use could result in a NullReferenceException",
            _ => "Some object type without format information"
        });
    // The example displays the following output:
    //    System.Globalization.CultureInfo object
    //    System.Globalization.DateTimeFormatInfo object
    //    System.Globalization.NumberFormatInfo object
    //    Some object type without format information
    //    A null object reference: Its use could result in a NullReferenceException
    复制代码
  • 相关阅读:
    MediaRecorder.AudioSource参数
    putty连接服务器
    支持库
    ImageView
    .net下MD5算法和加盐
    SqlHelper文件复习
    .net下连接数据库
    Windows Server 2003 R2 64位简体中文版下载
    gacutil.exe 注册assembly
    Sharepoint Powershell
  • 原文地址:https://www.cnblogs.com/sexintercourse/p/16618173.html
Copyright © 2020-2023  润新知