windows C#-弃元(上)

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

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

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

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

可以使用弃元来指定 Lambda 表达式中未使用的输入参数。 

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

元组和对象析构

如果应用程序代码使用某些元组元素,但忽略其他元素,这时使用弃元来处理元组就会很有用。 例如,以下 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 的模式匹配

弃元模式可通过 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

猜你喜欢

转载自blog.csdn.net/m0_72813396/article/details/143444608