record是C#9引入的新的引用类型,详细见官方文档:https://docs.microsoft.com/zh-cn/dotnet/csharp/whats-new/csharp-9#record-types
在C#中,引用类型有:interface,class,delegate,数组;现在record加入了进来,这是一个与类极度相似,但又不同的类型,重点在比较两个对象相等时,不是用引用地址作比较(虽然它是个引用类型),而是用“类型名{属性名1=属性值,属性名2=属性值,……}”(注1:这是一种形象但不严格的说法)。
DDD中,有实体和值对象的概念,其中值对象定义如下:
通过对象属性值来识别的对象,它将多个相关属性组合为一个概念整体——《实现领域驱动设计》
就是通过这个对象的各个属性相同不相同来判断是不是同一个值对象,这时,record就最合适不过了,它能直接判断两个实例化后的对象是否相等,。
record本质上个class,对反射,dapper的适配,面向对象的特征都是相同的,demo见:https://github.com/axzxs2001/Asp.NetCoreExperiment/blob/master/Asp.NetCoreExperiment/CSharp/RecordTypeDemo/Program.cs
using Dapper;
using Npgsql;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;namespace RecordTypeDemo
{class Program{static void Main(string[] args){//接口类型IShow show = new Entity1() { ID = 1, Name = "桂素伟" };Console.WriteLine(show);//输出结果:Entity1 { ID = 1, Name = 桂素伟 }//抽象类型Entity entity = new Entity1() { ID = 1, Name = "桂素伟" };Console.WriteLine(entity);//输出结果:Entity1 { ID = 1, Name = 桂素伟 }//注1:虽然 类型名{属性名1=属性值,属性名2=属性值,……} 相等,但比较结果是不等的Console.WriteLine($"show == entity结果:{show == entity}");//输出结果:show == entity结果::False//实体类型var entity1 = new Entity1() { ID = 1, Name = "桂素伟" };Console.WriteLine(entity1);//输出结果:Entity1 { ID = 1, Name = 桂素伟 }Console.WriteLine($"(entity1 == entity结果:{entity1 == entity}");//输出结果:(entity1 == entity结果:TrueConsole.WriteLine($"(entity1 == entity结果:{entity1.Equals(entity)}");//输出结果:(entity1 == entity结果:TrueAddEntity(entity);ReflectionTest(entity1);}/// <summary>/// 反射中使用record,和类相山/// </summary>/// <param name="entity"></param>static void ReflectionTest(Entity entity){var type = Assembly.GetExecutingAssembly().GetType("RecordTypeDemo.Entity");Console.WriteLine(type.IsClass);}/// <summary>/// 对dapper适配/// </summary>/// <param name="entity"></param>/// <returns></returns>static bool AddEntity(Entity entity){using (var con = new NpgsqlConnection("Server=127.0.0.1;Port=5432;UserId=postgres;Password=postgres2018;Database=postgres;")){var list = con.Query<Entity1>("select * from entitys").ToList();if (!list.Contains(entity)){con.Execute("insert into entitys(id,name) values(@id,@name)", entity);}return true;}/*表结构
CREATE TABLE public.entitys
(id integer NOT NULL DEFAULT nextval('entitys_id_seq'::regclass),name character varying(256) COLLATE pg_catalog."default",CONSTRAINT entitys_pkey PRIMARY KEY (id)
)
*/}}#region 面向对象特征和类一样/// <summary>/// 接口/// </summary>public interface IShow{void Show();}/// <summary>/// 抽象记录/// </summary>public abstract record Entity : IShow{public abstract int ID { get; set; }public abstract string Name { get; set; }public void Show(){Console.WriteLine($"{this.GetType().Name}:");Console.WriteLine($"{this.ToString()}");}}/// <summary>/// 记录/// </summary>public record Entity1 : Entity{public override int ID{get;set;}public override string Name{get;set;}}#endregion
}