Ця стаття є дзеркальною статтею машинного перекладу, будь ласка, натисніть тут, щоб перейти до оригінальної статті.

Вид: 3341|Відповідь: 0

[Джерело] .NET/C# новий тип запису функцій

[Копіювати посилання]
Опубліковано 02.10.2023 09:25:51 | | | |
Починаючи з C#9, можна використовувати модифікатор запису для визначення типу посилання, який надає вбудовану функціональність для інкапсуляції даних. C# 10 дозволяє синтаксис класу запису як синонім для уточнення типів посилання, а структури запису дозволяє визначати типи значень із тією ж функціональністю.

Сценарії використання для запису в C#(Відповіді ChatGPT):

Тип запису на C# — це нова функція, введена в останній версії. Він може використовуватися в багатьох сценаріях, зокрема, але не обмежуючись наступними:

Незмінний об'єкт даних: тип запису є незмінним, тобто після створення його значення властивості не можна змінювати. Це робить їх ідеальними для представлення незмінних структур даних, таких як об'єкти передачі (DTO) або налаштування конфігурації.
Об'єкти значення: тип запису можна використовувати для представлення об'єктів цінності, рівність яких визначається на основі значень атрибутів, а не еталонної еквівалентності. Це робить їх ідеальними для порівняння та зберігання об'єктів значень, таких як діапазони дат, координатні точки та інше.
Matching pattern: тип запису можна використовувати разом із matching pattern, що робить його зручнішим при роботі зі складними структурами даних. Ви можете використати відповідність шаблонів, щоб перевірити та витягти значення атрибутів об'єкта запису, щоб виконати відповідну дію.
Незмінні колекції: тип запису можна використовувати з типами незмінних колекцій, такими як ImmutableList, ImmutableDictionary тощо, для створення незмінних об'єктів колекції. Це гарантує, що зміст колекції не змінюється, що підвищує надійність і безпеку коду.
Це лише кілька випадків використання типу запису, і ви можете вирішити, чи використовувати цей тип запису, відповідно до ваших потреб і структури коду.
Різниця між записом, класом і структурою

Синтаксис, який використовується при оголошенні та інстанції класу чи структури, такий самий, як при записі операції. Просто замініть ключове слово класу на record або використовуйте structure записати замість struct. Аналогічно, клас запису підтримує той самий синтаксис для відношень спадкування. Різниця між записом і класом така:

  • Ви можете використовувати позиційні параметри в основному конструкторі для створення та втілення типів з незмінними властивостями.
  • Методи та оператори, які вказують на рівність або нерівність у класах (наприклад, Object.Equals(Object) та ==), вказують на рівність або нерівність значень у записі.
  • Ви можете використати вираз with для створення копії незмінного об'єкта з новим значенням у вибраному атрибуті.
  • Метод ToString запису створює рядок формату, який відображає назву типу об'єкта та імена й значення всіх його спільних властивостей.
  • Запис може бути успадкований від іншого запису. Але записи не можна успадкувати з класів, так само як і класи не можна успадкувати від записів.
  • Різниця між структурою запису та структурою полягає в тому, що компілятор синтезує методи для визначення рівності та ToString. Компілятор синтезує метод Deconstruct для структури запису позицій.


Компілятор синтезує спільну властивість лише ініціалізації для кожного основного параметра конструктора класу запису. У структурі запису компілятор синтезує властивості публічного читання/запису. Компілятор не створює властивостей для основних аргументів конструктора в типах класів і структур, які не містять модифікатор запису.

Запис

Тип посилання на клас запису (за замовчуванням: клас може бути опущений)
Тип значення структури запису

Граматика запису цукор

Насправді це рекордСинтаксис, і кінцевий результат — код класу або struct。 Візьмемо наступний код як приклад:

Нарешті, він компілює у наступний код:

використовуючи 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")]
[модуль: UnverifiableCode]
[модуль: System.Runtime.CompilerServices.RefSafetyRules(11)]

[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
публічний клас Особа Інформація : Еквівалентна<PersonInfo>
{
    [Згенерований компілятор]
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    приватний струнний <FirstName>k__BackingField;

    [Згенерований компілятор]
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    приватний струнний <LastName>k__BackingField;

    [Згенерований компілятор]
    захищений віртуальний тип EqualityContract
    {
        [Згенерований компілятор]
        отримати
        {
            тип повернення (PersonInfo);
        }
    }

    публічний рядок FirstName
    {
        [Згенерований компілятор]
        отримати
        {
            повернення <FirstName>k__BackingField;
        }
        [Згенерований компілятор]
        init
        {
            <FirstName>k__BackingField = значення;
        }
    }

    публічний рядковий Прізвище
    {
        [Згенерований компілятор]
        отримати
        {
            повернення <LastName>k__BackingField;
        }
        [Згенерований компілятор]
        init
        {
            <LastName>k__BackingField = значення;
        }
    }

    публічна PersonInfo(рядок Ім'я, рядок Прізвище)
    {
        <FirstName>k__BackingField = Ім'я;
        <LastName>k__BackingField = Прізвище;
        база.. ctor();
    }

    [Згенерований компілятор]
    публічне перевизначення рядка ToString()
    {
        StringBuilder stringBuilder = новий StringBuilder();
        stringBuilder.Append("PersonInfo");
        stringBuilder.Append(" { ");
        if (PrintMembers(stringBuilder))
        {
            stringBuilder.Append(' ');
        }
        stringBuilder.Append('}');
        return stringBuilder.ToString();
    }

    [Згенерований компілятор]
    захищений віртуальний bool PrintMembers (конструктор StringBuilder)
    {
        RuntimeHelpers.EnsureEnoughExecutionStack();
        будівник. Append("Ім'я = ");
        будівник. Append((object)Firstname);
        будівник. Append(", Прізвище = ");
        будівник. Append((об'єкт)Прізвище);
        Повернення True;
    }

    [System.Runtime.CompilerServices.NullableContext(2)]
    [Згенерований компілятор]
    публічний статичний оператор булів !=(PersonInfo зліва, PersonInfo праворуч)
    {
        Повернутися! (лівий == правий);
    }

    [System.Runtime.CompilerServices.NullableContext(2)]
    [Згенерований компілятор]
    публічний статичний бул-оператор ==(PersonInfo зліва, PersonInfo праворуч)
    {
        return (object)left == right || ((object)left != null && left. Equals(право));
    }

    [Згенерований компілятор]
    публічне перевизначення 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)]
    [Згенерований компілятор]
    публічне перевизначення bool Equals (об'єкт obj)
    {
        return Equals (obj як PersonInfo);
    }

    [System.Runtime.CompilerServices.NullableContext(2)]
    [Згенерований компілятор]
    публічний віртуальний bool Equals (PersonInfo інше)
    {
        повернути (об'єкт)це == інше || ((об'єкт)інше!= null && EqualityContract == інше. EqualityContract && EqualityComparer<string>. За замовчуванням. Equals(<FirstName>k__BackingField, інше<FirstName>. k__BackingField) та EqualityComparer<string>. За замовчуванням. Equals(<LastName>k__BackingField, інше<LastName>. k__BackingField));
    }

    [Згенерований компілятор]
    публічний віртуальний <Clone>PersonInfo $()
    {
        повернути нову PersonInfo(це);
    }

    [Згенерований компілятор]
    захищена PersonInfo(оригінал PersonInfo)
    {
        <FirstName>k__BackingField = оригінал. <FirstName>k__BackingField;
        <LastName>k__BackingField = оригінал. <LastName>k__BackingField;
    }

    [Згенерований компілятор]
    public void Deconstruct (виходить рядок FirstName, виходить рядок LastName)
    {
        FirstName = це. FirstName;
        Прізвище = це. Прізвище;
    }
}

Простір назв Microsoft.CodeAnalysis
{
    [Згенерований компілятор]
    [Вбудовано]
    внутрішній герметичний клас EmbeddedАтрибут: Атрибут
    {
    }
}

Namespace System.Runtime.CompilerServices
{
    [Згенерований компілятор]
    [Вбудований Microsoft.CodeAnalysis]
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | АтрибутеЦілі.Параметр | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = неправда, Inherited = false)]
    внутрішній запечатаний клас NullableAttribute : Атрибут
    {
        публічний байт для читання[] NullableFlags;

        public NullableAttribute(байт P_0)
        {
            байт[] масив = новий байт[1];
            масив[0] = P_0;
            NullableFlags = масив;
        }

        public NullableAttribute(byte[] P_0)
        {
            NullableFlags = P_0;
        }
    }

    [Згенерований компілятор]
    [Вбудований Microsoft.CodeAnalysis]
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = неправда, Inherited = false)]
    внутрішній запечатаний клас NullableContextAttribute : Атрибут
    {
        публічний байт Flag для читання;

        public NullableContextAttribute(байт P_0)
        {
            Прапор = P_0;
        }
    }

    [Згенерований компілятор]
    [Вбудований Microsoft.CodeAnalysis]
    [AttributeUsage(AttributeTargets.Module, AllowMultiple = неправда, Inherited = false)]
    внутрішній запечатаний клас RefSafetyRulesАтрибут: Атрибут
    {
        загальнодоступну версію для читання;

        публічний RefSafetyRulesAttribute(int P_0)
        {
            Версія = P_0;
        }
    }
}
Він автоматично генерує конструктори, переписує методи ToString, GetHashCode, Equals і автоматично генерує деякі методи.


p1 і p2 насправді є двома різними об'єктами, але оскільки компілятор автоматично генерував компаратор (IEquatable) і переписував методи Equals і GetHashCode, результат був істинним. Виклик методу ToString також дуже інтуїтивно інтуїтивний для виведення записаного значення. Як показано нижче:

.NET/C# реалізує власний компаратор IEqualityComparer
https://www.itsvse.com/thread-10643-1-1.html



Запис

необхіднийМодифікатор :required вказує, що поле або атрибут, який він застосовує, має бути ініціалізоване всіма конструкторами або за допомогою ініціалізатора об'єкта. Будь-який вираз, що використовується для ініціалізації нового екземпляра цього типу, повинен ініціалізувати всі необхідні елементи.
Посилання:Вхід за гіперпосиланням видно.

init: У C#9 і пізніших версіях ключове слово init визначає метод аксесора в властивості або індексаторі. Бібліотека лише для INIT призначає значення лише атрибутам або елементам індексатора під час побудови об'єкта. Це забезпечує незмінність, тому після ініціалізації об'єкта його вже не можна змінювати.
Посилання:Вхід за гіперпосиланням видно.

з: Якщо потрібно відтворити екземпляр з деякими модифікаціями, можна використати вираз з для реалізації неруйнівних змін. з виразом для створення нового екземпляра запису, який є копією існуючого екземпляра запису, змінюючи вказані властивості та поля.
Посилання:Вхід за гіперпосиланням видно.

Отже, запис можна визначити так:

Обов'язково, іно, не кажучи вже про те, що з синтаксичним цукором, це будеВикликайте автоматично <Clone>згенерований метод $а потім змінити значення атрибута. Наступним чином:



Код:



Атрибут запису

Іноді потрібно додати деякі функції до атрибутів, такі як функції серіалізації JSON, інформація про опис тощо.



Ресурси:

Вхід за гіперпосиланням видно.
Вхід за гіперпосиланням видно.





Попередній:ASP.NET Core (24) базується на Refit, високопродуктивній комунікації MemoryPack
Наступний:GitHub використовує REST API для перегляду розмірів репозиторіїв
Застереження:
Усе програмне забезпечення, програмні матеріали або статті, опубліковані Code Farmer Network, призначені лише для навчання та досліджень; Вищезазначений контент не повинен використовуватися в комерційних чи незаконних цілях, інакше користувачі несуть усі наслідки. Інформація на цьому сайті надходить з Інтернету, і спори щодо авторських прав не мають до цього сайту. Ви повинні повністю видалити вищезазначений контент зі свого комп'ютера протягом 24 годин після завантаження. Якщо вам подобається програма, будь ласка, підтримуйте справжнє програмне забезпечення, купуйте реєстрацію та отримайте кращі справжні послуги. Якщо є будь-яке порушення, будь ласка, зв'яжіться з нами електронною поштою.

Mail To:help@itsvse.com