Csharp/C#教程:使用C#9中records作为强类型ID的实例教程分享

强类型ID

实体通常是整数,GUID或者string类型,因为数据库直接支持这些类型,但是,如果实体的ID的类型是一样的,比如都是整数的ID,这有可能会出现ID值传错的问题,看下边的示例。

publicvoidAddProductToOrder(intorderId,intproductId,intcount) { ... } ... //这个地方,参数传错了 AddProductToOrder(productId,orderId,intcount);

上面的代码可以很好地通过检查并编译,但是在运行的时候就出问题了,这是逻辑bug。

幸运的是,可以定义强类型id来解决这个问题,这个想法很简单,为每个实体的ID声明一个特定的类型,现在需要这样写:

//使用强类型ID代替整数ID publicvoidAddProductToOrder(OrderIdorderId,ProductIdproductId,intcount) { ... } ... //这个地方,参数传错了 AddProductToOrder(productId,orderId,intcount);

在上面的代码中,我们犯了与第一个示例相同的错误(交换productId和orderId),但是在这种情况下,类型不同,因此编译器会捕获该错误并报告错误,我们仍然需要对其进行修复,但是至少在生产中并没有爆炸。

编写一个强类型的id
publicreadonlystructProductId:IEquatable<ProductId> { publicProductId(intvalue) { Value=value; } publicintValue{get;} publicboolEquals(ProductIdother)=>other.Value==Value; publicoverrideboolEquals(objectobj)=>objisProductIdother&&Equals(other); publicoverrideintGetHashCode()=>Value.GetHashCode(); publicoverridestringToString()=>$"ProductId{Value}"; publicstaticbooloperator==(ProductIda,ProductIdb)=>a.Equals(b); publicstaticbooloperator!=(ProductIda,ProductIdb)=>!a.Equals(b); }

上面的代码没什么难的,但是如果每个实体都需要的话,那确实有点麻烦,在C#9可以使用sourcegenerators来完成这些,但是C#9还引入了另一个功能,使用起来更方便。

Record类型

Record类型是具有内置不变性和值语义的引用类型,它和上面我们写的强类型是一样的(手动写的成员实现Equals,GetHashCode等等),在代码中使用也非常简洁,如果我们ProductId使用record重写类型,就是下边这样:

publicrecordProductId(intValue);

是的,您没看错,这是一行,而上面的代码是一大段,它完成了我们手动执行的所有操作(实际上,还多了很多!)。

主要区别在于:我们的手动实现是struct,即值类型,但是记录是引用类型,这意味着它们可以为null,这可能不是主要问题,尤其是在使用可为空的引用类型的情况下,但是要知道这一点。

现在为模型中的每个实体编写一个强类型的id是不是很简单,使用Record非常方便,当然,还有其他问题需要考虑,例如JSON序列化,与EntityFrameworkCore一起使用等,但这是另一篇文章的故事!

上述就是C#学习教程:使用C#9中records作为强类型ID的实例教程分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/903530.html

(0)
上一篇 2021年10月21日
下一篇 2021年10月21日

精彩推荐