• C# 9.0 record和with的定义及使用


    C# 9 引入record,它一种可以创建的新引用类型,而不是类或结构。 C# 10 添加了 record structs,以便可以将记录定义为值类型。 记录与类不同,区别在于record类型使用基于值的相等性。 两个记录类型的变量在它们的类型和值都相同时,它们是相等的。with 表达式在 C# 9.0 及更高版本中可用,使用修改的特定属性和字段生成其操作数的副本。以下介绍C# 9.0 record和with的定义及使用。

    1、record定义及使用

    record类型的实际是一个引用类型 ,但具备值类型的行为。重写了Equals等对象类型的比较方法,在两个不同引用的record对象的内容相同时,对两者进行==比较,判断两者相等为true。重写了ToString()方法,便于输出属性内容。还重写了GetHashCode()Equals()方法。

    1)定义record类型

    public record Language
    {
        public string LastName { get; }
        public string FirstName { get; }
        public Language(string first, string last) => (FirstName, LastName) = (first, last);
    }
    

    创建使用:

    Language lang = new("JavaScript", "JS");//Language lang = new Language("JavaScript", "JS");
    

    用对象初始化器进行初始化,则在属性中使用init关键字,

    如下,

    public record Language
    {
        public string? FirstName { get; init; }
        public string? LastName { get; init; }
    }
    

    创建使用:

    Language lang = new(){ FirstName = "JavaScript", LastName = "JS"};//Language lang = new(){ FirstName = "JavaScript", LastName = "JS"}
    

    注意:由于有set访问器,所以它支持用对象初始化器进行初始化,如想用构造函数进行初始化,可以添加自己的构造函数。 init 就是自动生成了一个对 私有只读字段 的封装,多了一种让你初始化 只读字段 的方式。

    上面定义是不可变类型record,定义可变类型rcord代码,如下,

    public record Language
    {
        public string? FirstName { get; set; }
        public string? LastName { get; set; }
    }
    

    2)解构函数

    record对象能解构成元组,需要为record添加解构函数Deconstruct。通过构造函数的参数传入,并通过位置解构函数提取出来。

    例如,

    public record Language
    { 
        public string FirstName { get; init; } 
        public string LastName { get; init; }
        public Language(string firstName, string lastName) 
          => (FirstName, LastName) = (firstName, lastName);
        public void Deconstruct(out string firstName, out string lastName) 
          => (firstName, lastName) = (FirstName, LastName);
    }
    

    使用:

    var language = new Language("JavaScript", "JS"); // 位置构造函数
    var (firstName, lastName) = person;                        // 位置解构函数
    

    3)定义protected属性

    可以使用更简单的方式,代码如下,

    public record Language(string firstName, string lastName)
    {
        protected string FirstName { get; init; } = firstName;
        protected string LastName { get; init; } = lastName;
    }
    

    4)record的面向对象

    在面向对象方面,支持继承,多态等所有特性。record的基类也是objectrecord只能从记录继承,record不能定义为static的,但是可以有static成员。不能从类继承调用父类构造函数可以使用方式如下,

     public record Student(string firstName, string lastName, int ID) : Language(firstName, lastName);
    

    2、with的使用

    with表达式,用于拷贝原有对象,并对特定属性进行修改。在 C# 9.0 中,with 表达式的左侧操作数必须为with。 从 C# 10 开始,with 表达式的左侧操作数也可以为with或匿名类型。

    例如,

    using System;
    public class InheritanceExample
    {
        public record Point(int X, int Y);
        public record NamedPoint(string Name, int X, int Y) : Point(X, Y);
        public static void Main()
        {
            Point p1 = new NamedPoint("A", 0, 0);
            Point p2 = p1 with { X = 5, Y = 3 };
            Console.WriteLine(p2 is NamedPoint);  // output: True
            Console.WriteLine(p2);  // output: NamedPoint { X = 5, Y = 3, Name = A }
        }
    }
    

    对于引用类型成员,在复制操作数时仅复制对成员实例的引用。 副本和原始操作数都具有对同一引用类型实例的访问权限。

    例如,

    using System;
    using System.Collections.Generic;
    public class ExampleWithReferenceType
    {
        public record TaggedNumber(int Number, List Tags)
        {
            public string PrintTags() => string.Join(", ", Tags);
        }
        public static void Main()
        {
            var original = new TaggedNumber(1, new List { "A", "B" });
            var copy = original with { Number = 2 };
            Console.WriteLine($"Tags of {nameof(copy)}: {copy.PrintTags()}");
            // output: Tags of copy: A, B
            original.Tags.Add("C");
            Console.WriteLine($"Tags of {nameof(copy)}: {copy.PrintTags()}");
            // output: Tags of copy: A, B, C
        }
    }
  • 相关阅读:
    oracle创建表空间及查看表空间和使用情况
    Elasticsearch基础操作演示总结
    9.0 堆体系结构概述之GC
    猿创征文|【Linux】Linux中的gdb调试器的使用
    【数据结构-哈希表 一】【原地哈希】:缺失的第一个正整数
    【Jmeter】在进行综合场景压测时,由于不同的请求,要求所占比例不同,那如何实现呢?
    自定义View的绘制:Xfermode用法解析
    linux服务器部署项目
    Linux的OpenLava配置
    服务中找不mysql 错误 error 2003 ERROR 2003 (HY000):
  • 原文地址:https://blog.csdn.net/lwf3115841/article/details/134272297