|
|
Публикувано в 2.10.2023 г. 9:25:51 ч.
|
|
|
|

Започвайки от C# 9, можете да използвате модификатора на записа, за да дефинирате тип референция, който предоставя вградена функционалност за капсулиране на данни. C# 10 позволява синтаксиса на класа на запис като синоним за изясняване на референтните типове и позволява структурата на записа да дефинира типове стойности чрез същата функционалност.
Случаи на употреба за записване в C#(ChatGPT отговаря):
Типът на запис на C# е нова функция, въведена в най-новата версия. Може да се използва в много ситуации, включително, но не само, следните:
Неизменяем обект на данни: Типът запис е неизменяем, което означава, че веднъж създаден, стойността на свойството му не може да бъде променяна. Това ги прави идеални за представяне на неизменни структури от данни като трансферни обекти (DTOs) или конфигурационни настройки. Обекти на стойност: Типът запис може да се използва за представяне на стойностни обекти, чието равенство се определя въз основа на стойностите на атрибутите, а не на референтната еквивалентност. Това ги прави идеални за сравняване и съхранение на стойностни обекти като диапазони от дати, координатни точки и други. Съвпадение на шаблони: Типът запис може да се използва заедно с съвпадение на шаблони, което го прави по-удобен при работа със сложни структури от данни. Можете да използвате съвпадение на шаблони, за да проверите и извлечете стойностите на атрибутите на обекта на записа, за да извършите съответното действие. Неизменяеми колекции: Типът запис може да се използва с неизменяеми колекции като ImmutableList, ImmutableDictionary и др., за създаване на обекти на неизменяеми колекции. Това гарантира, че съдържанието на колекцията не се променя, като по този начин се подобрява надеждността и сигурността на кода. Това са само някои от случаите на използване на типа запис, и можете да решите дали да използвате този тип запис според вашите специфични нужди и структура на кода. Разлика между запис и клас и структура
Синтаксисът, използван при деклариране и инстанциране на клас или структура, е същият като при записване на операция. Просто заменете класовата ключова дума с запис, или използвайте структура запис вместо struct. По същия начин класът запис поддържа същия синтаксис за наследствени отношения. Разликата между запис и клас е следната:
- Можеш да използваш позиционни параметри в основния конструктор, за да създаваш и инстанцираш типове с неизменни свойства.
- Методи и оператори, които показват референтно равенство или неравенство в класовете (например Object.Equals(Object) и ==), показват равенство или неравенство на стойности в записа.
- Можеш да използваш with expression, за да създадеш копие на неизменим обект с нова стойност в избрания атрибут.
- Методът ToString на записа създава низ, който показва името на типа на обекта и имената и стойностите на всички негови общи свойства.
- Запис може да бъде наследен от друг запис. Но записите не могат да бъдат наследени от класове, нито класовете могат да бъдат наследени от записи.
- Разликата между структурата на записа и самата структура е, че компилаторът синтезира методи за определяне на равенство и ToString. Компилаторът синтезира метода на деконструкция за структурата на записа на позицията.
Компилаторът синтезира общо свойство само за инициализация за всеки основен конструктор параметър в класа на записи. В структурата на записа компилаторът синтезира публични свойства за четене/запис. Компилаторът не създава свойства за основните конструкторски аргументи в типовете класове и структури, които не съдържат модификатора на записите.
запис
Тип референтен клас на запис (по подразбиране: клас може да бъде пропуснат) Тип на стойност на структурата запис
Граматика на записа захар
Рекордът всъщност е такъвСинтаксичен захар, и крайният резултат е класов или структурен код。 Вземете следния код за пример:
Накрая се компилира в следния код:
използвайки System; използвайки System.Collections.Generic; използвайки System.Diagnostics; използвайки System.Reflection; използване на System.Runtime.CompilerServices; използвайки System.Security; използвайки System.Security.Permissions; използвайки System.Text; използване на Microsoft.CodeAnalysis;
[асемблер: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue | DebuggableAttribute.DebuggingModes.DisableOptimizations)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [модул: UnverififiableCode] [модул: System.Runtime.CompilerServices.RefSafetyRules(11)]
[System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] публичен клас PersonInfo : IEquaable<PersonInfo>
{ [КомпилаторГенериран] [DebuggerBrowsable(DebuggerBrowsableState.Never)] Частен k__BackingField за четене <FirstName>на струна;
[КомпилаторГенериран] [DebuggerBrowsable(DebuggerBrowsableState.Never)] Частен струнен k__BackingField;<LastName>
[КомпилаторГенериран] защитен виртуален тип EqualityContract { [КомпилаторГенериран] получавам { тип връщане (PersonInfo); } }
публичен низ FirstName { [КомпилаторГенериран] получавам { връщане <FirstName>k__BackingField; } [КомпилаторГенериран] Първоначален { <FirstName>k__BackingField = стойност; } }
публичен низ Фамилия { [КомпилаторГенериран] получавам { връщане <LastName>k__BackingField; } [КомпилаторГенериран] Първоначален { <LastName>k__BackingField = стойност; } }
public PersonInfo(низ Първо име, низ Фамилия) { <FirstName>k__BackingField = Първо име; <LastName>k__BackingField = Фамилия; база.. ctor(); }
[КомпилаторГенериран] публичен override низ ToString() { StringBuilder stringBuilder = нов StringBuilder(); stringBuilder.Append("PersonInfo"); stringBuilder.Append(" { "); if (PrintMembers(stringBuilder)) { stringBuilder.Append(' '); } stringBuilder.Append('}'); return stringBuilder.ToString(); }
[КомпилаторГенериран] защитен виртуален bool PrintMembers (StringBuilder builder) { RuntimeHelpers.EnsureSufficientExecutionStack(); Строител. Append("Първо име = "); Строител. Append((object)FirstName); Строител. Append(", Фамилия = "); Строител. Append((object)LastName); върни се истински; }
[System.Runtime.CompilerServices.NullableContext(2)] [КомпилаторГенериран] публичен оператор на статичен бул!=(PersonInfo вляво, PersonInfo вдясно) { връщане! (ляво == дясно); }
[System.Runtime.CompilerServices.NullableContext(2)] [КомпилаторГенериран] публичен статичен bool оператор ==(PersonInfo вляво, PersonInfo вдясно) { return (object)left == дясно || ((object)left != null && left. Равно (дясно)); }
[КомпилаторГенериран] public override int GetHashCode() { return (EqualityComparer<Type>. Default.GetHashCode(EqualityContract) * -1521134295 + EqualityComparer<string>. Default.GetHashCode(<FirstName>k__BackingField)) * -1521134295 + EqualityComparer<string>. Default.GetHashCode(<LastName>k__BackingField); }
[System.Runtime.CompilerServices.NullableContext(2)] [КомпилаторГенериран] public override bool Equals(object obj) { return Equals (obj като PersonInfo); }
[System.Runtime.CompilerServices.NullableContext(2)] [КомпилаторГенериран] публичен виртуален bool Equals(PersonInfo друго) { return (object)this == other || ((object)other != null && EqualityContract == друго. EqualityContract && EqualityComparer<string>. Default. Equals(<FirstName>k__BackingField, other.<FirstName>k__BackingField) && EqualityComparer<string>. Default. Equals(<LastName>k__BackingField, other.<LastName>k__BackingField)); }
[КомпилаторГенериран] публичен виртуален PersonInfo <Clone>$() { връщане на нов PersonInfo(това); }
[КомпилаторГенериран] Защитен PersonInfo (PersonInfo оригинал) { <FirstName>k__BackingField = оригинал. <FirstName>k__BackingField; <LastName>k__BackingField = оригинал. <LastName>k__BackingField; }
[КомпилаторГенериран] public void Deconstruct (излиза низ FirstName, излиза низ LastName) { FirstName = това. FirstName; Фамилия = това. Фамилия; }
}
namespace Microsoft.CodeAnalysis
{ [КомпилаторГенериран] [Вградено] вътрешен запечатан клас EmbeddedAttribute : Атрибут { }
}
namespace System.Runtime.CompilerServices
{ [КомпилаторГенериран] [Microsoft.CodeAnalysis.Вграден] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | АтрибутиЦели.Параметър | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] вътрешен запечатан клас NullableAttribute : Атрибут { публичен четен байт[] NullableFlags;
public NullableAttribute(байт P_0) { байт[] масив = нов байт[1]; array[0] = P_0; NullableFlags = масив; }
public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } }
[КомпилаторГенериран] [Microsoft.CodeAnalysis.Вграден] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Метод | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] вътрешен запечатан клас NullableContextAttribute : Атрибут { публичен за четене на байт Flag;
public NullableContextAttribute(байт P_0) { Флаг = P_0; } }
[КомпилаторГенериран] [Microsoft.CodeAnalysis.Вграден] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] вътрешен запечатан клас RefSafetyRulesАтрибут : Атрибут { публично четене на Int версия;
public RefSafetyRulesAttribute(int P_0) { Версия = P_0; } }
} Автоматично генерира конструктори, пренаписва методите ToString, GetHashCode, Equals и автоматично генерира някои методи.
p1 и p2 всъщност са два различни обекта, но тъй като компилаторът автоматично генерираше компаратора (IEquatable) и пренаписа методите Equals и GetHashCode, резултатът беше верен. Извикването на метода ToString също е много интуитивно за извеждане на записаната стойност. Както е показано по-долу:
запис
ИзискваМодификаторът :required показва, че полето или атрибут, който прилага, трябва да бъдат инициализирани от всички конструктори или чрез инициализатора на обекта. Всеки израз, използван за инициализация на нов екземпляр от този тип, трябва да инициализира всички необходими членове. Препратка:Входът към хиперлинк е видим.
Първоначален: В C# 9 и по-нататък ключовата дума init дефинира метода за достъп в свойство или индексатор. Библиотеката само за INIT присвоява стойности само на атрибути или индексаторни елементи по време на конструирането на обекти. Това налага неизменност, така че след като обектът бъде инициализиран, той вече не може да бъде променян. Препратка:Входът към хиперлинк е видим.
с: Ако трябва да репликирате инстанция с някои модификации, можете да използвате с израза, за да реализирате неразрушителни промени. с израз за създаване на нова инстанция на запис, която е копие на съществуваща инстанция на запис, като се модифицират зададените свойства и полета. Препратка:Входът към хиперлинк е видим.
Така записът може да се дефинира по следния начин:
Необходимо, да не говорим, че всъщност е синтактичен захар, това щеИзвикай автоматично генерирания <Clone>метод $и след това да променят стойността на атрибута. Както следва:
Код:
Атрибут на запис
Понякога трябва да добавим някои функции към атрибутите, като функции за сериализация на JSON, информация за описание и др.
Ресурси:
Входът към хиперлинк е видим.
Входът към хиперлинк е видим.
|
Предишен:ASP.NET Core (24) е базиран на Refit, високопроизводителна комуникация MemoryPackСледващ:GitHub използва REST API за преглед на размерите на хранилищата
|