.net 5 何时使用记录vs类vs结构

.net 5 何时使用记录vs类vs结构,.net-5,c#-9.0,c#-record-type,.net 5,C# 9.0,C# Record Type,我应该为所有在控制器和服务层之间移动数据的DTO类使用Record 我是否应该对所有请求绑定使用Record,因为理想情况下,我希望发送到控制器的请求对于我的asp.net api是不可变的 什么是唱片 SearchParameters是否应该制作一个记录?短版本 您的数据类型可以是值类型吗?使用struct。不您的类型是否描述了一个值,比如最好是不可变状态?使用记录 否则请使用class。所以 是的,如果DTO是单向流,请为其使用records 是的,对于记录 是的,SearchPara

我应该为所有在控制器和服务层之间移动数据的DTO类使用
Record

  • 我是否应该对所有请求绑定使用
    Record
    ,因为理想情况下,我希望发送到控制器的请求对于我的asp.net api是不可变的

  • 什么是唱片

    SearchParameters
    是否应该制作一个
    记录

    短版本 您的数据类型可以是值类型吗?使用
    struct
    。不您的类型是否描述了一个值,比如最好是不可变状态?使用
    记录

    否则请使用
    class
    。所以

  • 是的,如果DTO是单向流,请为其使用
    record
    s
  • 是的,对于
    记录
  • 是的,
    SearchParameters
    记录的理想用户案例
  • 有关
    记录
    使用的更多实际示例,您可以检查此项

    长版本
    struct
    class
    record
    是用户数据类型

    结构是值类型。类是引用类型。默认情况下,记录是不可变的引用类型

    当您需要某种层次结构来描述您的数据类型,如继承或指向另一个
    struct
    struct
    或基本上指向其他对象的对象时,您需要引用类型

    当您希望您的类型在默认情况下以值为导向时,记录可以解决此问题。记录是引用类型,但具有面向值的语义

    说到这里,问问你自己这些问题


    您的数据类型是否尊重以下所有方面:

  • 它在逻辑上表示单个值,类似于基本类型(int、double等)
  • 它的实例大小小于16字节
  • 它是不变的
  • 它不必经常装箱
    • 是吗?它应该是
      struct
    • 没有?它应该是某种引用类型

    您的数据类型是否封装了某种复杂的值?这个值是不变的吗?您是否在单向(单向)流中使用它

    • 是吗?使用
      记录
    • 没有?使用
    顺便说一句:别忘了。在C#10.0中会有匿名记录

    笔记 如果将记录实例设置为可变的,则它可以是可变的

    类程序
    {
    静态void Main()
    {
    var测试=新Foo(“a”);
    Console.WriteLine(test.MutableProperty);
    test.MutableProperty=15;
    Console.WriteLine(test.MutableProperty);
    //test.Bar=“new string”;//将不编译
    }
    }
    公共记录Foo(字符串栏)
    {
    公共双可变属性{get;set;}=10.0;
    }
    

    默认情况下,记录副本是记录的浅层副本。副本是由C#编译器发出的特殊克隆方法创建的。值类型成员已装箱。你可以做记录的深度复制

    请参见此示例(使用C#9.0中的顶级功能):

    使用系统;
    使用System.Collections.Generic;
    使用静态系统控制台;
    var foo=newsomerecord(newlist());
    var fooAsCopy=foo;
    var fooWithDifferentitlist=foo和{List=new List(){“a”,“b”};
    var differentfootwithsamelist=新的SomeRecord(foo.List);
    foo.List.添加(“a”);
    WriteLine($“foo中的计数:{foo.List.Count}”);//1.
    WriteLine($“Fooscopy中的计数:{fooscopy.List.Count}”);//1.
    WriteLine($“FooWithDifferentitList中的计数:{FooWithDifferentitList.List.Count}”);//2.
    WriteLine($“DifferentFootWithSameList中的计数:{DifferentFootWithSameList.List.Count}”);//1.
    WriteLine($“Equals(foo&fooscopy):{Equals(foo,fooscopy)}”);//真的
    WriteLine($“Equals(foo&footwithdifferentitlist):{Equals(foo,footwithdifferentitlist)}”);//错,列表是不同的
    WriteLine($“Equals(foo&differentitfoothsamelist):{Equals(foo,differentitfoothsamelist)}”);//是的,列表是一样的
    WriteLine($“ReferenceEquals(foo&fooscopy):{ReferenceEquals(foo,fooscopy)}”);//是的,因为纯粹的浅拷贝
    WriteLine($“ReferenceEquals(foo&footwithdifferentitlist):{ReferenceEquals(foo,footwithdifferentitlist)}”);//错误,列表不同
    WriteLine($“ReferenceEquals(foo&differentitfoothsamelist):{ReferenceEquals(foo,differentitfoothsamelist)}”);//False,相同记录类型的不同实例
    var bar=新的SomeRecordWithValueProperty();
    var=bar;
    var barAsDeepCopy=带有{};//深拷贝
    写线($“等于(条形和条形):{Equals(条形,条形)}”);//真的
    WriteLine($“Equals(bar和barAsDeepCopy):{Equals(bar,barAsDeepCopy)}”);//正确,价值平等
    WriteLine($“ReferenceEquals(bar&Baroscopy):{ReferenceEquals(bar,Baroscopy)}”);//没错,肤浅的复制品
    WriteLine($“ReferenceEquals(bar&BarasDepCopy):{ReferenceEquals(bar,BarasDepCopy)}”);//假,深拷贝
    bar.MutableProperty=2;
    bara.MutableProperty=3;
    barAsDeepCopy.MutableProperty=3;
    WriteLine($“bar.MutableProperty={bar.MutableProperty}| baroscopy.MutableProperty={baroscopy.MutableProperty}”);
    写线($“等于(条形和条形):{Equals(条形,条形)}”);//True,可变属性已装箱,并且两个实例在可变属性中的值均为3。
    WriteLine($“Equals(bar和barAsDeepCopy):{Equals(bar,barAsDeepCopy)}”);//真的
    WriteLine($“ReferenceEquals(bar&Baroscopy):{ReferenceEquals(bar,Baroscopy)}”);//真的
    WriteLine($“ReferenceEquals(bar&BarasDepCopy):{ReferenceEquals(bar,BarasDepCopy)}”);//假的
    公共记录(列表);
    公共记录SomeRecordWithValueProperty
    {
    public int MutableProperty{get;set;}=1;//此属性已装箱
    }
    
    在这里,性能损失是显而易见的。要在记录实例中复制的数据越大,性能损失就越大。属
      public class HomeController 
      { 
        public IHttpAction Search([FromBody] SearchParameters searchParams)
        {
           _service.Search(searchParams);
        }
      }