C# 下记录(Record)详解

ops/2024/9/20 1:25:27/ 标签: c#

在C# 9.0中,引入了一个新的关键字:record。record关键字用于定义记录类型,这是一种不可变的数据结构,用于表示具有明确字段名称和类型的数据集。本文将详细介绍C#中record类型的使用和特点,以及如何通过记录记录器(如Console.WriteLine)与用户输入进行互动。

1. 记录(Record)的基本概念

记录类型是一种不可变的数据结构,它由字段组成,每个字段都有明确的名字和类型。在C#中,record类型提供了一种快捷的方式来创建具有明确字段名称和类型的数据集。record类型的定义如下:

public record RecordType(FieldType1 field1, FieldType2 field2, ...);

其中,RecordType是记录类型的名称,FieldType1、FieldType2等是字段的类型,字段之间用逗号分隔。

2. 记录(Record)的特点

record类型具有以下特点:

  • 不可变性:record类型一旦创建,其字段的值就不能被修改。这意味着record类型是一个值类型,而不是引用类型。
  • 明确字段名称:record类型的字段名称在记录类型中是唯一的,这使得记录类型的使用更加清晰和易于理解。
  • 简洁性:record类型允许你快速地定义具有明确字段名称和类型的数据集,而无需编写额外的代码。
  • 自动实现属性:record类型会自动为每个字段生成一个私有字段,并为其提供一个公共属性,方便进行字段值的访问和赋值。

3. 不同类型的记录

C#中的record类型可以用于表示不同类型的数据集。以下是一些常见的record类型示例:

// 表示个人信息的record类型
public record Person(string Name, int Age);// 表示订单信息的record类型
public record Order(string ProductName, decimal Price, int Quantity);// 表示日期和时间的record类型
public record DateTimeRecord(DateTime Date, TimeSpan Time);

在这些示例中,我们定义了用于表示个人信息、订单信息和日期时间的record类型。

4. 记录记录器(如Console.WriteLine)的使用方法

记录记录器是一种用于记录数据的方法,它可以将记录的字段值输出到控制台或其他输出设备。在C#中,你可以使用Console.WriteLine方法作为记录记录器。

下面是一个使用record类型和Console.WriteLine记录记录实例的示例:

// 定义一个record类型
public record Person(string Name, int Age);// 使用record类型创建记录实例
Person person = new Person("张三", 30);// 使用Console.WriteLine记录记录实例
Console.WriteLine($"姓名:{person.Name}, 年龄:{person.Age}");

在这个例子中,我们定义了一个Person record类型,并使用Console.WriteLine方法输出了记录实例的字段值。

5. 与用户输入的互动

你可以使用record类型与用户输入进行互动,例如,创建一个用于输入和显示个人信息的程序。以下是一个简单的示例:

// 定义一个record类型
public record Person(string Name, int Age);// 用户输入记录实例的字段值
Console.Write("请输入姓名:");
string name = Console.ReadLine();
Console.Write("请输入年龄:");
int age = int.Parse(Console.ReadLine());// 使用用户输入的字段值创建记录实例
Person person = new Person(name, age);// 使用Console.WriteLine记录记录实例
Console.WriteLine($"姓名:{person.Name}, 年龄:{person.Age}");

在这个例子中,我们使用Console.ReadLine方法获取用户输入的姓名和年龄,并使用这些输入值创建了一个Person record类型的实例。然后,我们使用Console.WriteLine方法输出了记录实例的字段值。

6. 记录示例代码

下面是一个完整的记录示例,它定义了一个表示学生信息的record类型,并使用用户输入和记录记录器与用户互动:

using System;public record Student(string Name, int Age, string Major);public class Program
{public static void Main(string[] args){// 用户输入记录实例的字段值Console.Write("请输入学生姓名:");string name = Console.ReadLine();Console.Write("请输入学生年龄:");int age = int.Parse(Console.ReadLine());Console.Write("请输入学生专业:");string major = Console.ReadLine();// 使用用户输入的字段值创建记录实例Student student = new Student(name, age, major);// 使用Console.WriteLine记录记录实例Console.WriteLine($"姓名:{student.Name}, 年龄:{student.Age}, 专业:{student.Major}");}
}

在这个例子中,我们定义了一个Student record类型,它有三个字段:Name、Age和Major。然后,我们使用Console.ReadLine方法获取用户输入的姓名、年龄和专业,并使用这些输入值创建了一个Student record类型的实例。最后,我们使用Console.WriteLine方法输出了记录实例的字段值。

7. 记录(Record)与类(Class)的区别

虽然record类型和类都可以用来表示具有明确字段名称和类型的数据集,但它们之间存在一些区别:

  • 不可变性:record类型是不可变的,而类是可变的。这意味着一旦record类型创建,其字段的值就不能被修改;而对于类,你可以修改其字段的值。
  • 自动实现属性:record类型会自动为每个字段生成一个私有字段和一个公共属性,而类需要你手动为每个字段编写get和set方法。
  • 性能:由于record类型是不可变的,它在某些情况下可能比类具有更好的性能,例如,当你不需要修改记录实例的字段值时。

8.record类型实现接口

在C#中,记录类型本身是不支持实现接口的。记录类型被设计得简单、轻量,并且不支持传统意义上的继承。这意味着您无法直接在记录类型上实现接口。但是,您可以通过使用记录类型和类的组合来实现类似的功能。您可以采用以下方法:

  1. 定义仅包含必要字段的记录类型。
  2. 创建一个实现所需接口并具有记录类型属性的类。
  3. 使用该类作为记录类型的包装器来提供接口实现。

下面是一个例子来说明这一点:

using System;
using System.Collections.Generic;
using System.Linq;public interface IEntity
{int Id { get; set; }string Name { get; set; }
}public record Person(string Name, int Age);public class EntityWrapper : IEntity
{public int Id { get; set; }public string Name { get; set; }public EntityWrapper(int id, string name){Id = id;Name = name;}public Person AsRecord(){return new Person(Name, Id);}
}public class Program
{public static void Main(){EntityWrapper entityWrapper = new EntityWrapper(1, "Alice");IEntity entity = entityWrapper.AsRecord();Console.WriteLine($"Id: {entity.Id}, Name: {entity.Name}");}
}

在此示例中,我们有一个具有两个属性的 IEntity 接口:Id 和 Name。我们定义一个包含“姓名”和“年龄”字段的人员记录类型。然后,我们创建一个 EntityWrapper 类,该类实现 IEntity 并具有 Person 类型的属性。EntityWrapper 类通过包装记录类型来提供接口实现。这种方法允许您使用记录类型的轻量级和不可变属性,同时仍然能够实现应用程序逻辑所需的接口。

9. 结论

C#中的record类型是一种简洁、易用且具有明确字段名称和类型的不可变数据结构。它提供了快速定义数据集的途径,并具有自动实现属性的特点。record类型可以用于表示不同类型的数据集,并与用户输入进行互动。通过使用record类型和记录记录器(如Console.WriteLine),你可以更方便地处理和输出记录实例的字段值。掌握record类型的使用,可以使你的C#编程更加高效和简洁。


http://www.ppmy.cn/ops/7790.html

相关文章

使用easyexcel将csv转为excel

一.背景 供应商系统下载的csv文件不支持域控(主要是第三方wps服务不能对csv文件加密,但是可以对office系列产品进行权限访问的加密控制)。因此思路就改为现将csv文件转为excel文件,然后对excel文件进行加域控制。本文主要介绍如何…

数据结构--双向链表

在讲双向链表之前,我们先了解一下链表的分类: 链表的结构⾮常多样,主要分为带头与不带头、单向与双向、循环与不循环。三个种类可以任意搭配,所以总共可以形成八种链表,但是最常用的是单向不带头不循环链表和双向带头循…

html、css、QQ音乐移动端静态页面,资源免费分享,可作为参考,提供InsCode在线运行演示

CSDN将我上传的免费资源私自变成VIP专享资源,且作为作者的我不可修改为免费资源,不可删除,寻找客服无果,很愤怒,(我发布免费资源就是希望大家能免费一起用、一起学习),接下来继续寻找…

代码托管基础操作

在待上传代码文件夹中右键,打开Git Bash Here依次输入以下命令: git init(在本地初始化一个代码仓库,具体表现为会在你的文件夹里出现一个隐藏的.git文件夹) git add .(先把代码放到本地的一个缓冲区)添加当前目录下的…

命理八字之答案之书前端uniapp效果实现

#uniapp# #答案之书# 不讲废话&#xff0c;先上截图 <div class"padding"><div class"flex align-center justify-center" style"padding-top:100px;"><div class"radarContainer"><div id"radarBox"…

初识ansible变量及实例配置

目录 1、为什么要使用变量 2、变量分类 3、 变量详解 3.1 vars,vars_files , group_vars 3.1 .1 vars 剧本中定义变量 3.1.2 vars_file 将变量存放到一个文件中&#xff0c;并在剧本中引用 3.1.3 group_vars 创建一个变量文件给某个组使用 实例1-根据不同的主机…

[ LeetCode ] 题刷刷(Python)-第35题:搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 nums 为 无重复元素 的 升序 排列数组 请必须使用时间复杂度为 O(log n) 的算法。 示例 示例 1: 输入: …

Django老项目升级到新版本

手上有个 Django 老项目&#xff0c;一直跑得好好的&#xff0c;好几年没动过了&#xff0c;维护费收得正爽&#xff0c;没想到客户来了个新的运营人员&#xff0c;丢了个改动需求过来。我一看也没啥大改&#xff0c;就答应了。大意了。 问题 刚开始改&#xff0c;我这种老鸟…

MongoDB聚合运算符:$sampleRate

MongoDB聚合运算符&#xff1a;$sampleRate 文章目录 MongoDB聚合运算符&#xff1a;$sampleRate语法使用举例 $sampleRate聚合运算符用$match&#xff0c;按照指定的抽样比例&#xff0c;从输入的文档中随机选择相应的文档。 语法 { $sampleRate: <non-negative float>…

使用Spring Boot整合定时任务(Schedule)

1、添加依赖&#xff1a; 在pom.xml文件中添加Spring Boot的定时任务依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId> </dependency> 2、创建定时任务类&#xff1a; 创建…

搜索+剪枝,LeetCode 216. 组合总和 III

目录 一、题目 1、题目描述 2、接口描述 python3 cpp 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 python3 cpp 一、题目 1、题目描述 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字1到9每个数字 最多…

Linux下跟踪某个进程的内核处理时延消耗情况

1.利用系统自动的trace功能&#xff0c;编辑如下脚本&#xff0c;vim trace_process.sh #!/bin/sh cd /sys/kernel/debug/tracing/ #清空原有跟踪信息 echo > trace echo nop > current_tracer #设置要跟踪的进程 echo "pid281255" echo 281255 > set_ftra…

【项目】仿muduo库One Thread One Loop式主从Reactor模型实现高并发服务器(TcpServer板块)

【项目】仿muduo库One Thread One Loop式主从Reactor模型实现⾼并发服务器&#xff08;TcpServer板块&#xff09; 一、思路图二、模式关系图三、定时器的设计1、Linux本身给我们的定时器2、我们自己实现的定时器&#xff08;1&#xff09;代码部分&#xff08;2&#xff09;思…

ASP.Net MVC 登录页面实现RSA非对称加密

一、什么是RSA非对称加密 RSA是1977年由罗纳德李维斯特&#xff08;Ron Rivest&#xff09;、阿迪萨莫尔&#xff08;Adi Shamir&#xff09;和伦纳德阿德曼&#xff08;Leonard Adleman&#xff09;一起提出的。 RSA算法是一种非对称加密算法&#xff0c;与对称加密算法不同…

【CSS】CSS实现元素逐渐消失(实现元素透明逐渐消失/模糊)

mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 10%);mask-image 属性用于定义一个遮罩&#xff0c;它可以隐藏元素的一部分或全部内容。在这个示例中&#xff0c;我们使用 mask-image 属性来定义一个线性渐变的遮罩&#xff0c;使得列表项的内…

达梦数据库执行sql报错:数据溢出

数据库执行sql报错数据溢出 单独查询对应的数字进行计算是不是超过了某个字段类型的上限或下限 如果已经超过了&#xff0c;进行对字段进行cast类型转换处理&#xff0c;转换为dec num都可以尝试 这里就是从 max(T.BLOCK_ID as dec*8192t.bytes)/1024/1024 max_MB,换成了这个…

rust 卸载重新安装 安装

原因&#xff1a;接触区块链时报错 linking with x86_64-w64-mingw32-gcc failed: exit code: 1 Rust编译需要C环境&#xff0c;如果你没有&#xff0c;Rust也能安装成功&#xff0c;只是无法编译代码 C的编译工具有两个&#xff0c;一个是msvc&#xff0c;也就是visual studi…

汽车视频智能剪辑解决方案,满足用户对高品质汽车视频的追求

随着汽车智能化和互联网技术的快速发展&#xff0c;车载视频已经成为现代驾驶生活不可或缺的一部分。然而面对海量的行车视频&#xff0c;如何高效地剪辑、整理并分享这些精彩瞬间&#xff0c;一直是车主和汽车内容创作者们所面临的难题。美摄科技&#xff0c;作为领先的视频智…

k8s调度场景

15个KUBERNETES调度情景实用指南 Kubernetes调度是确保集群中的Pod在适当节点上运行的关键组件。通过灵活配置调度策略&#xff0c;可以提高资源利用率、负载平衡和高可用性。 在本文中&#xff0c;我们将深入探讨一些实际的Kubernetes调度场景&#xff0c;并提供相应的配置示…

【AI自媒体制作】【AI工具】Midjourney中文站

Midjourney Midjourney中文站, MJ中文站 - 专业AI绘图网站 广场 绘画广场&#xff1a; 包含大量其他用户生成好的图片&#xff0c;可以自由保存。 视频广场&#xff1a; 普通用户目前只支持查看&#xff0c;无法下载 画夹广场&#xff1a; 有很多免费的画夹&#xff0c;比…