当前位置: 首页 > news >正文

遂宁移动网站建设江苏网站建设网络推广

遂宁移动网站建设,江苏网站建设网络推广,京东商城网站建设教程,网站制作的报价大约是多少.NET 5.0已经发布#xff0c;C# 9.0也为我们带来了许多新特性#xff0c;其中最让我印象深刻的就是init和record type#xff0c;很多文章已经把这两个新特性讨论的差不多了#xff0c;本文不再详细讨论#xff0c;而是通过使用角度来思考这两个特性。initinit是C# 9.0中引… .NET 5.0已经发布C# 9.0也为我们带来了许多新特性其中最让我印象深刻的就是init和record type很多文章已经把这两个新特性讨论的差不多了本文不再详细讨论而是通过使用角度来思考这两个特性。initinit是C# 9.0中引入的新的访问器它允许被修饰的属性在对象初始化的时候被赋值其他场景作为只读属性的存在。直接使用的话可能感受不到init的意义所以我们先看看之前是如何设置属性为只读的。private set设置属性为只读设置只读属性有很多种方式本文基于private set来讨论。首先声明一个产品类如下代码所示我们把Id设置成了只读这个时候也就只能通过构造函数来赋值了。在通常情况下实体的唯一标识是不可更改的同时也要防止Id被意外更改。public class Product {public Product(int id){this.Id  id;}public int Id { get; private set; }//public int Id { get; }public string ProductName { get; set; }public string Description { get; set; } }class Program {static void Main(string[] args){Product product  new Product(1){ProductName  test001,Description  Just a description};Console.WriteLine($Current Product Id: {product.Id},\n\rProduct Name: {product.ProductName}, \n\rProduct Description: {product.Description});//运行结果//Current Product Id: 1,//Product Name: test001,//Product Description: Just a descriptionConsole.ReadKey();} } record方式设置只读使用init方式是非常简单的只需要把private set改成init就行了public int Id { get; init; } 两者比较为了方便比较我们可以将ProductName设置成了private set然后通过ILSpy来查看一下编译后的代码看看编译后的Id和ProductName有何不同咋一看貌似没啥区别都使用到了initonly来修饰。但是如果仅仅只是替换声明方式那么这个新特性似乎就没有什么意义了。接下来我们看第二张图如图标记的那样区别还是很明显的通过init修饰的属性并没有完全替换掉set由此看来微软在设计init的时候还是挺用心思的也为后面的赋值留下了入口。instance void modreq([System.Runtime]System.Runtime.CompilerServices.IsExternalInit) set_Id (int32 value) 另外在赋值的时候使用private set修饰的属性需要定义构造函数通过构造函数赋值。而使用了init修饰的属性则不需要定义构造函数直接在对象初始化器中赋值即可。Product product  new Product {Id  1,ProductName  test001,Description  Just a description };product.Id  2;//Error CS8852 Init-only property or indexer Product.Id can only be assigned in an object initializer, or on this or base in an instance constructor or an init accessor. 如上代码所示只读属性Id的赋值并没有在构造函数中赋值毕竟当一个类的只读字段十分多的时候构造函数也变得复杂。而且在赋值好之后无法修改这和我们对只读属性在通常情况下的理解是一致的。另外通过init修饰的好处便是省却了一部分只读属性在操作上的复杂性使得对象的声明与赋值更加直观。在合适的场景下选择最好的编程方式是程序员的一贯追求千万不要为了炫技而把init当成了茴字的第N种写法到处去问。recordrecord是一个非常有用的特性它是不可变类型其相等性是通过内部的几个属性来确定的同时它支持我们以更加方便的方式、像定义值类型那样来定义不可变引用类型。我们把之前的Product类改成record类型如下所示public record Product {public Product(int id, string productName, string description)  (Id, ProductName, Description)  (id, productName, description);public int Id { get; }public string ProductName { get; }public string Description { get; } } 然后查看一下IL可以看到record会被编译成类同时继承了System.Object并实现了IEquatable泛型接口。编译器为我们提供的几个重要方法如下EqualsGetHashCode()ClonePrintMembers和ToString()比较重要的三个方法Equals通过图片中的代码我们知道比较两个record对象首先需要比较类型是否相同然后再依次比较内部属性。GetHashCode()record类型通过基类型以及所有的属性及字段的方式来计算HashCode这在整个继承层次结构中增强了基于值的相等性也就意味着两个同名同姓的人不会被认为是同一个人Clone这个方法貌似非常简单实在看不出有什么特别的地方那么我们通过后面的内容再来解释这个方法。record在DDD值对象中的应用record之前的定义方式了解DDD值对象的小伙伴应该想到了record类型的特性非常像DDD中关于值对象的描述比如不可变性、其相等于是基于其内部的属性的等等我们先来看下值类型的定义方式。public abstract class ValueObject {public static bool operator (ValueObject left, ValueObject right){if (ReferenceEquals(left, null) ^ ReferenceEquals(right, null)){return false;}return ReferenceEquals(left, null) || left.Equals(right);}public static bool operator !(ValueObject left, ValueObject right){return !(left  right);}protected abstract IEnumerableobject GetEqualityComponents();public override bool Equals(object obj){if (obj  null || obj.GetType() ! GetType()){return false;}var other  (ValueObject)obj;return this.GetEqualityComponents().SequenceEqual(other.GetEqualityComponents());}public override int GetHashCode(){return GetEqualityComponents().Select(x  x ! null ? x.GetHashCode() : 0).Aggregate((x, y)  x ^ y);}// Other utility methods } public class Address : ValueObject {public string Street { get; private set; }public string City { get; private set; }public string State { get; private set; }public string Country { get; private set; }public string ZipCode { get; private set; }public Address(string street, string city, string state, string country, string zipcode){Street  street;City  city;State  state;Country  country;ZipCode  zipcode;}protected override IEnumerableobject GetEqualityComponents(){// Using a yield return statement to return each element one at a timeyield return Street;yield return City;yield return State;yield return Country;yield return ZipCode;}public override string ToString(){return $Street: {Street}, City: {City}, State: {State}, Country: {Country}, ZipCode: {ZipCode};} } main方法如下static void Main(string[] args) {Address address1  new Address(aaa, bbb, ccc, ddd, fff);Console.WriteLine($address1: {address1});Address address2  new Address(aaa, bbb, ccc, ddd, fff);Console.WriteLine($address2: {address2});Console.WriteLine($address1  address2: {address1  address2});string jsonAddress1  address1.ToJson();Address jsonAddress1Deserialize  jsonAddress1.FromJsonAddress();Console.WriteLine($jsonAddress1Deserialize  address1: {jsonAddress1Deserialize  address1});Console.ReadKey(); } 运行结果如下基于class: address1: Street: aaa, City: bbb, State: ccc, Country: ddd, ZipCode: fff address2: Street: aaa, City: bbb, State: ccc, Country: ddd, ZipCode: fff address1  address2: True jsonAddress1Deserialize  address1: True 采用record方式定义如果有大量的值对象需要我们编写这无疑是加重我们的开发量的这个时候record就派上用场了最简洁的record风格的代码如下所示只有一行public record Address(string Street, string City, string State, string Country, string ZipCode); IL代码如下图所示从图中我们也可以看到record类型的对象默认情况下用到了init来限制属性的只读特性。main方法代码不变运行结果也没有因为Address从class变成record而发生改变基于record: address1: Street: aaa, City: bbb, State: ccc, Country: ddd, ZipCode: fff address2: Street: aaa, City: bbb, State: ccc, Country: ddd, ZipCode: fff address1  address2: True jsonAddress1Deserialize  address1: True 如此看来我们的代码节省的不止一点点而是太多太多了是不是很爽啊。record对象属性值的更改使用方式如下class Program {static void Main(string[] args){Address address1  new Address(aaa, bbb, ccc, ddd, fff);Console.WriteLine($1. address1: {address1});Address addressWith  address1 with { Street  ############ };Console.ReadKey();} }public record Address(string Street, string City, string State, string Country, string ZipCode); 通过ILSpy查看如下所示private static void Main(string[] args) {Address address1  new Address(aaa, bbb, ccc, ddd, fff);Console.WriteLine($1. address1: {address1});Address address2  address1.Clone$();address2.Street  ############;Address addressWith  address2;Console.ReadKey(); } 由此可以看到record在更改的时候实际上是通过调用Clone而产生了浅拷贝的对象这也非常符合DDD ValueObject的设计理念。参考https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/implement-value-objectshttps://deviq.com/value-object/
http://www.zqtcl.cn/news/643080/

相关文章:

  • 摄影网站在线建设办公室设计装修
  • 深圳市移动端网站建设游戏网站建设与策划方案
  • wap版网站 加app提示厦门网站seo优化
  • 旅游网站 功能建设银行网站会员
  • 公园网站建设wordpress 分类目录使用英文
  • 苏州高端网站设计制作wordpress改固定连接
  • 门户网站开源sae安装wordpress
  • 建设彩票网站需要哪些要求城乡与住房建设厅网站首页
  • 公司做网站费用计入什么科目网络建设规划
  • 外贸网站建设案例深圳设计网站培训
  • 龙岗地区做网站公司北京装饰公司排行 2019
  • 大企业网站建设方案wordpress博客模板查询
  • 手机网站建设动态公司做网站效果怎么样
  • 网站推广和优化教程上海网络科技有限公司招聘
  • 即墨建网站价格商城二次开发
  • 网站排名易下拉教程怎么做网店运营
  • 聊城做网站公司聊城博达海外服务器租用多少钱一年
  • 手机上网站做国外销售都上什么网站
  • 网站建设与管理报告书做电销有什么资料网站
  • 网站建设哪家最好企业商城网站建设方案
  • 舟山市建设工程质量监督站网站网页版微信二维码加载失败
  • 金融网站html5模板给自己家的公司做网站好做吗
  • 新农村建设投诉在哪个网站上海做电缆桥架的公司网站
  • 免费行情100个软件网络优化论文
  • asp.net动态的网站开发个人业务网站带后台
  • 控制网站的大量访问关于实验室建设的英文网站
  • 中国容桂品牌网站建设怎么自己做个网站做链接跳转
  • 安徽省建设工程协会网站昆明官网seo厂家
  • 品牌整合推广搜狗优化好的网站
  • 娄底手机网站制作深圳网站建设怎么做