C# 9 record 并非简单属性 POCO 的语法糖
C# 9 record 并非简单属性 POCO 的语法糖
最近升级专案到大统一 .NET 5 并使用 C#9 语法尝试改写套件,发现之前以为 record 只是简单属性 POCO 的简化语法糖的认知是错误。
另外因为 POCO 属于需定义口语词,这边在本文定义简单属性 POCO
为 public class 类别 {public string ID{get;set}/*略*/}
只有属性的简单类别代码
一. rocord 的确底层是 class,但,不是单纯简单属性 POCO class
可以看 IL Spy 反编译程序码,发现系统帮我们做了很多事
二. 预设
生成的是属性是 {get;init;}
不是 {get;set;}
,这代表设定值
时间点在 constructor(建构式)
,延伸产生immutable(不可变)
特性,也代表 record 预设为thread-safe(线程安全)
,因为都是取得一样的值。
所以当你使用 Dapper 类似框架查询完 POCO 资料,想做修改属性时会报 CS8852 无法修改错误。
三. 预设比较
逻辑改变
可以看TimCorey写的例子,可以看到预设 class 跟 record 的 == 差异,线上测试连结
public class Program
{
public static void Main()
{
var record1Obj1 = new record1(FirstName: "Lin", LastName: "WeiHan");
var record1Obj2 = new record1(FirstName: "Lin", LastName: "WeiHan");
Console.WriteLine(record1Obj1 == record1Obj2);//true
var class1Obj1 = new Class1() { FirstName = "Lin", LastName = "WeiHan" };
var class2Obj2 = new Class1() { FirstName = "Lin", LastName = "WeiHan" };
Console.WriteLine(class1Obj1 == class2Obj2);//false
}
}
public record record1(string FirstName,string LastName);
public class Class1
{
public string FirstName {get;init;}
public string LastName{get;init;}
}
因为 record override ==
跟 Equals
,认为只要是同一个 record 类型,并且属性值都一样
,系统就会认定为true
,也就是俗称的structural equality
,可以看 IL Spy 反编译代码
public virtual bool Equals(record2? other)
{
return (object)other != null && EqualityContract == other!.EqualityContract && EqualityComparer<string>.Default.Equals(FirstName, other!.FirstName) && EqualityComparer<string>.Default.Equals(LastName, other!.LastName);
}
跟 object class 预设会去取得 RuntimeHelpers.GetHashCode
Handle 逻辑不相同。
四. GetHashCode也做了类似逻辑,所以属性值一样,HashCode会得到一样的值
,线上测试连结
IL Spy 反编译代码
public override int GetHashCode()
{
return (EqualityComparer<Type>.Default.GetHashCode(EqualityContract) * -1521134295 + EqualityComparer<string>.Default.GetHashCode(FirstName)) * -1521134295 + EqualityComparer<string>.Default.GetHashCode(LastName);
}
五. 注意不能把 record 当作一定是 immutable(不可变)
,原因在微软没有限制
以下写法...
public record record2
{
public string FirstName {get;set;}
public string LastName{get;set;}
}
准许修改 {get;init;}
为 {get;set}
,将会导致 immutable 跟 thread-safe 特性消失
六. record 会帮忙生成可读性好的 ToString 实作
以下图片为比较一般 class 跟 record 生成的 ToString 差别
七. record 帮忙生成 extend IEquatable<类别>
,并实作强型别public virtual bool Equals(Record1? other)
这代表可以避免原本public override bool Equals(object? obj)
需要先 unboxing 再 boxing 的效能损耗
问题
阅读资料:
C# 9 record 并非简单属性 POCO 的语法糖的更多相关文章
- OC:属性、点语法、KVC
//属性的属性 属性定义在一个 .h文件里,在这个.h文件里可以定义实例变量(就是这个类的特征),也可以通过 @protery(属性约束关键字) 属性名字类型 属性名 来定义一些属性,在prope ...
- C#语法糖之第一篇:自动属性&隐式类型
今天给大家分享一下C#语法糖的简单的两个知识点吧. 自动属性:在 C# 4.0 和更高版本中,当属性的访问器中不需要其他逻辑时,自动实现的属性可使属性声明更加简洁. 客户端代码还可通过这些属性创建对象 ...
- C#在属性中用Lambda语法
今天看代码改功能的时候遇到了个比较奇怪的地方,在属性里也能用Lambda,我看了好久,也不是很理解,我都开始怀疑这是不是属性了,又在群里讨论了下这个问题,觉得有必要记下来,因为又涨知识了. 问题1:这 ...
- iOS语法糖 简单却不那么简单
转载作者 香蕉大大 (Github) 开发过程中我特别喜欢用语法糖,原因很简单,懒得看到一堆长长的代码,但是语法糖我今天无意中看到更有意思的玩法.这里暂时吧把今天新学到的知识点整理一下希望大家喜欢,如 ...
- Python进阶-XVIII 封装、(属性、静态方法、类方法)语法糖、反射
1.封装 类中的私有化:属性的私有化和方法的私有化 会用到私有的这个概念de场景 1.隐藏起一个属性 不想让类的外部调用 2.我想保护这个属性,不想让属性随意被改变 3.我想保护这个属性,不被子类继承 ...
- ES6 class 语法糖不能直接定义原型上的属性
今天注意到两个东西: 1.为了模拟面向对象,JavaScript的class语法糖屏蔽了原型的概念 class A{ a = 1 // 注意!!这里定义的不是在prototype上的属性,而是给实 ...
- 4.简单的 GNU 汇编语法
芯片启动时很多设备没有初始化,需要汇编语言进行准备. 简单的GNU汇编语法: 1 label: instruction @ comment label :标号,类似于外号,为所在位置做标号,可以通过这 ...
- salesforce 零基础学习(二十九)Record Types简单介绍
在项目中我们可能会遇见这种情况,不同的Profile拥有不同的页面,页面中的PickList标签可能显示不同的值.这个时候,使用Record Types可以很便捷的搞定需求. Record Types ...
- EF框架step by step(5)—处理实体简单属性
EF框架会对实体进行跟踪,对实体的每个属性当前值和原始值及其状态进行跟踪,记录.当前值是指实体属性当前的被赋予的值,而原始值是指实体最初从数据库读取或者附加到DbContext时的值. 先通过简单的代 ...
随机推荐
- tomcat在eclipse里部署
先下载安装包,解压缩,运行安装文件(端口:8080,下一步 指定jdk安装路径,记住tomcat的安装位置) 安装程序的位置 和 安装后的位置不一样 ...
- .net core autofac asyncinterceptor 异步拦截器开发
autofac使用拦截器实现AOP,是基于Castle.Core的.然而Castle.Core并未提供原生异步支持.所以需要使用帮助类实现,这在autofac官方文档的已知问题中有详细说明: http ...
- php7.1安装openssl扩展
1,进入到PHP源码目录中的ext中的openssl目录 2,phpize 3,./configure --with-openssl --with-php-config=/usr/local/php/ ...
- DataSkew 数据倾斜
date: 2020-04-21 19:38:00 updated: 2020-04-24 10:26:00 DataSkew 数据倾斜 1. Hive 里的数据倾斜 1.1 null值 空值 尽量提 ...
- java如何实现一个Future
实现Futrue接口 public class MsgFuture<V> implements java.util.concurrent.Future<V> { ... ... ...
- Mybatis入门 Mybatis存在的意义 解决的问题 基本操作
Mybatis入门 Mybatis的作用 解决的问题 基本操作 为什么要学MyBatis 我们链接操作数据库需要做的步骤 package Test; import java.sql.*; public ...
- php 实现签名验签
本人php菜鸟,主要使用php实现简单的签名验签功能 以下php代码使用的密钥格式为pem格式,其他证书格式可以使用openssl进行转换(未安装请实现安装): 以下是.p12文件导出pem格式公私钥 ...
- 服务器性能监控神器nmon使用介绍
介绍 Nmon (Nigel's Monitor)是由IBM 提供.免费监控 AIX 系统与 Linux 系统资源的工具.该工具可将服务器系统资源耗用情况收集起来并输出一个特定的文件,并可利用 exc ...
- solr 文档一
[在此处输入文章标题] 参考博客: http://blog.csdn.net/matthewei6/article/details/50620600 基础环境搭建 solr版本5.5.5: 一.sol ...
- 如何优雅阻止view UI 的 Switch 切换?
一.官方文档提供的方法 个人觉得官方提供的方法有时候不能够满足现实需求,第二点是view UI版本必须是4.0.0版本及以上才能使用这个开关组件. 二.自定义方法解决 ①将开关禁用掉 加一个 dis ...