【C#】一record

本文探讨了C#中枚举的使用,位运算符的应用,包括与、或、异或,并通过实例解析事件的声明与委托。还涉及类结构、异常处理以及如何正确地在类内外组织代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1

splitStrings去掉了空格就是没有空隙的一行。

3

enum{}不能写在类里;

namespace{}

        class{}

                Main(){}

4
错误    CS1656    无法为“item”赋值,因为它是“foreach 迭代变量” 
5

和c int* arrayHere =new int [6];区别不大

6

class:消息:必须大写才合适?

7枚举&位运算

&验证

|添加

^删去

7

异常:很严峻呀 

8

 应当是把这个放到【GreetingManager】类里。如果偏不,就是出现这个错误

GreetingDelegate delegate1;

9【不重要】

        可以当做“标准” 

10

 记录下。事件只能放到类里搞,类外出错;所以要定义【GreetPeople】函数,让类外调用。

11

解读:                事件                                +=类.委托(类.静态函数);

12

13

这种finally也是没输出的。

using System;
class MyApp
{
    static int f(int i)
    {
        return 100 / i;
    }
    public static void Main()
    {
        try
        {
            int dZero = f(0);
        }
        finally
        {
            Console.WriteLine("finally");
        }
    }
}

5还没“四舍五入”进上去。呃呃呃

。。。

namespace ConsoleApplication1
{
    [Flags]
    enum Days2
    {
        None = 0x0,
        Sunday = 0x1,
        Monday = 0x2,
        Tuesday = 0x4,
        Wednesday = 0x8,
        Thursday = 0x10,
        Friday = 0x20,
        Saturday = 0x40
    }
    class MyApp
    {
        static void Main()
        {
            Days2 meetingDays = Days2.Tuesday | Days2.Thursday;
            Console.WriteLine(meetingDays.ToString());

            bool test = (meetingDays & Days2.Thursday) == Days2.Thursday;
            Console.WriteLine("Thursday {0} a meeting day.", test == true ? "is" : "is not");

            meetingDays = meetingDays ^ Days2.Tuesday;
            Console.WriteLine(meetingDays);
        }
    }
}

<think>好的,我现在需要深入解析C#中的record类型。首先,我得回想下自己之前学过的关于record的知识,可能还需要查阅些资料来确保准确性。 首先,record是在C# 9引入的,对吧?它的主要用途是什么?我记得它是用来创建不可变的数据模型,比如DTO或者值对象。相比class和struct,record有什么特别之处呢? 然后,record的关键特性可能包括基于值的相等性、不可变性、with表达式等等。需要详细解释这些特性。比如,基于值的相等性意味着两个record实例如果所有属性值都相同,它们就被视为相等,而不像引用类型那样比较引用地址。 接下来,record的语法结构。默认情况下,record是引用类型,但行为类似于值类型。声明方式可以是record class或者record struct,不过C# 10开始支持record struct。所以需要提到这两种情况。 不可变性方面,record的属性默认是否是只读的?比如,使用init访问器,这样属性只能在初始化时被赋值。或者是否需要在声明时显式指定readonly?可能需要具体例子说明。 然后,with表达式的作用是什么?它允许我们基于现有实例创建个新实例,并修改某些属性。这对于不可变类型非常有用,因为每次修改都会生成个新对象,而不是改变原对象。 还有,record自动生成的成员有哪些?比如Equals、GetHashCode、ToString等方法会被编译器自动生成,这些方法都是基于属性值来处理的。这能减少样板代码,提高开发效率。 可能还需要比较record和class的区别,比如在相等性判断上的不同,以及record在模式匹配中的优势。此外,继承方面,record可以继承其他record,但不能继承class,反之亦然。这点需要注意。 有没有什么注意事项?比如,如果record包含可变属性,可能会破坏基于值的相等性,或者导致意外行为。所以通常建议保持record的完全不可变。 另外,解构功能是否支持?record是否允许解构,就像元组那样?可能需要检查如何通过Deconstruct方法来实现。 最后,应用场景举例,比如在领域驱动设计中的值对象,或者在微服务间传输数据的DTO,使用record可以简化代码并确保数据不可变。 在整理这些点时,需要确保每个部分的准确性,可能需要验证些细节,比如init访问器的行为,或者with表达式的具体用法。同时,要注意结构清晰,分点解释,让读者能够逐步理解record的各个方面。</think>C# 的 `record` 类型是 C# 9 引入的重要特性,专为**不可变数据模型**设计。以下是其核心特性与使用场景的深入解析: --- ### 、核心特性 1. **基于值的相等性** - 自动生成 `Equals` 和 `GetHashCode` 方法,比较属性值而非引用地址 ```csharp var p1 = new Person("Alice", 30); var p2 = new Person("Alice", 30); Console.WriteLine(p1 == p2); // 输出 True(值相等) ``` 2. **不可变性(默认行为)** - 属性默认使用 `init` 访问器,对象创建后无法修改 ```csharp public record Person(string Name, int Age); // 属性为只读 ``` 3. **`with` 表达式** - 基于现有实例创建新对象(类似函数式编程的"复制-修改") ```csharp var person2 = person1 with { Age = 31 }; // 生成新对象 ``` 4. **自动生成方法** - 编译器生成 `ToString()`(输出结构化的属性值) - 支持解构操作(可通过 `Deconstruct` 方法提取属性) ```csharp var (name, age) = person1; // 解构为元组 ``` --- ### 二、语法变体 1. **`record class`(默认)** - 引用类型,但基于值语义比较 ```csharp public record Student(string Id, string Major); ``` 2. **`record struct`(C# 10+)** - 值类型,适用于轻量级数据 ```csharp public record struct Point(int X, int Y); ``` --- ### 三、高级用法 1. **自定义行为** - 可手动重写自动生成的方法 ```csharp public record Book(string Title) { public string ISBN { get; init; } = GenerateISBN(); // 自定义初始化逻辑 } ``` 2. **继承支持** - `record` 可继承其他 `record`,但不能继承 `class` ```csharp public record Employee(string Name, string Department) : Person(Name, 0); ``` --- ### 四、适用场景 1. **DTO(数据传输对象)** - 简化 API 请求/响应模型的创建 2. **领域模型中的值对象** - 确保数据不可变,避免副作用 3. **模式匹配** - 结合 `switch` 表达式实现高效数据匹配 ```csharp var result = person switch { { Age: >= 18 } => "Adult", _ => "Minor" }; ``` --- ### 五、与 class 的关键差异 | 特性 | `record` | `class` | |---------------------|------------------------------|----------------------| | 相等性 | 值相等 | 引用相等 | | 不可变性 | 默认属性只读 | 需手动实现 | | `ToString()` | 自动生成属性摘要 | 返回类型名称 | | 克隆 | 内置 `with` 表达式 | 需手动实现深拷贝 | --- ### 六、注意事项 - 若需要可变性,可显式声明 `set` 访问器,但会破坏值相等语义 - 避免在 `record` 中封装复杂业务逻辑,保持其数据容器的定位 - 深度嵌套对象时,`with` 表达式只执行浅拷贝 通过合理使用 `record`,可以显著减少样板代码,提高数据模型的安全性和表达力,尤其适合函数式编程风格和领域驱动设计(DDD)场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值