Как да използваме неизменност в C #

Неизменността е характеристика на функционалните езици за програмиране, която улеснява писането, тестването и поддръжката на програмите. Въпреки това неизменността не се поддържа от много императивни езици за програмиране. Доскоро C # не поддържаше неизменност от кутията. 

Това се променя с въвеждането на записи в C # 9, което е достъпно за предварителен преглед в .NET 5. Въпреки това, ние можем да внедрим неизменност в по-ранните версии на C #, като използваме пространството от имена System.Collections.Immutable, което се предлага като NuGet пакет. 

Неизменяем обект се дефинира като обект, който не може да бъде променен, след като е създаден. За много случаи на употреба, като например обекти за трансфер на данни, неизменността е желана функция. Тази статия обсъжда защо може да искаме да се възползваме от неизменността и как можем да приложим неизменността в C #.

За да работите с примерите за кодове, предоставени в тази статия, трябва да имате Visual Studio 2019 инсталиран във вашата система. Ако все още нямате копие, можете да изтеглите Visual Studio 2019 тук. 

Създайте проект за приложение на конзола .NET Core в Visual Studio

Първо, нека създадем проект за приложение на конзола .NET Core в Visual Studio. Ако приемем, че Visual Studio 2019 е инсталиран във вашата система, следвайте стъпките, описани по-долу, за да създадете нов проект за приложение на конзола .NET Core в Visual Studio.

  1. Стартирайте Visual Studio IDE.
  2. Щракнете върху „Създаване на нов проект“.
  3. В прозореца „Създаване на нов проект“ изберете „Console App (.NET Core)“ от показания списък с шаблони.
  4. Щракнете върху Напред. 
  5. В показания след това прозорец „Конфигуриране на вашия нов проект“ посочете името и местоположението на новия проект.
  6. Щракнете върху Създаване. 

Това ще създаде нов проект за приложение на конзола .NET Core в Visual Studio 2019. Ще използваме този проект, за да илюстрираме неизменност в следващите раздели на тази статия.

Инсталирайте пакета System.Collection.Immutable NuGet

За да работите с неизменяеми типове, трябва да инсталирате пакета System.Collections.Immutable от NuGet. Можете да направите това или чрез диспечера на пакети NuGet вътре в IDE на Visual Studio 2019, или като изпълните следната команда в конзолата на диспечера на пакети NuGet:

Система за инсталиране на пакети. Колекции. Неизменяема

Този пакет включва колекция от безопасни за нишки класове, известни също като неизменяеми колекции.

Разберете неизменността и записите в C # 9

Обект за прехвърляне на данни е класически пример за това кога искате неизменност. Екземпляр на DTO често се сериализира, за да може да бъде независим от технологията, използвана в края на потребителя. Естествено, когато прехвърляте обект от данни между база данни и клиент, бихте искали да гарантирате, че обектът не може да бъде променен - ​​и точно това е целта на DTO. Можете да прочетете повече за използването на обекти за трансфер на данни в C # от по-ранната ми статия тук. 

За да създадете неизменяеми DTO, можете да се възползвате от ReadOnlyCollection или нишките безопасни неизменни типове колекции в System.Collections.Immutable пространство от имена. Като алтернатива можете да се възползвате от типовете записи в C # 9, за да внедрите неизменяеми DTO.

Тип запис в C # 9 е лек, неизменяем тип данни (или лек клас), който има само свойства за четене. Тъй като типът на записа е неизменен, той е безопасен за нишки и не може да мутира или променя, след като е създаден.

Можете да инициализирате тип запис само вътре в конструктор. Създаването на тип запис за клас (Автор в този пример) е толкова просто, колкото следния кодов фрагмент.

клас данни Автор (int Id, низ firstName, низ lastName, низ адрес);

Можете също така да напишете типа запис на автора, както е показано в кодовия фрагмент, даден по-долу:

клас на публични данни Автор {

    public int Id {get; в него; }

    публичен низ firstName {get; в него; }

    публичен низ lastName {get; в него; }

    публичен низов адрес {get; в него; }

}

Обърнете внимание на използването на ключовата дума data при деклариране на типа запис. Ключовата дума data, когато се използва в декларацията на клас, маркира типа като запис. Можете да се възползвате от екземпляр от тип запис, за да предавате данни през слоевете, като в същото време гарантирате неизменност на DTO.

System.Collections.Immutable пространство от имена

Неизменните колекции са тези, чиито членове не могат да се променят, след като са създадени. Пространството от имена System.Collections.Immutable включва няколко неизменяеми колекции. Това пространство от имена съдържа неизменяеми версии на списъци, речници, масиви, хешове, стекове и опашки.

ImmutableStack може да се използва за изтласкване и изскачане на елементи по същия начин, по който го правим с променливите стекове. Тъй като обаче ImmutableStack е неизменяема колекция, нейните елементи не могат да бъдат променяни. Така че, когато се обадите на метода pop за изскачане на елемент от стека, за вас се създава нов стек и оригиналният стек остава непроменен.

Нека илюстрираме това с пример. Следният кодов фрагмент показва как можете да изтласкате елементи върху неизменяем стек.

var stack = ImmutableStack.Empty;

за (int i = 0; i <10; i ++)

{

    stack = stack.Push (i);

}

Следващата програма демонстрира, че елементите на неизменяем стек не могат да бъдат променяни.

клас Програма

    {      

        static void Main (низ [] аргументи)

        {

            var stack = ImmutableStack.Empty;

            за (int i = 0; i <10; i ++)

            {

                stack = stack.Push (i);

            }

            Console.WriteLine ("Брой елементи в оригиналния стек:

             "+ stack.Count ());

            var newStack = stack.Pop ();

            Console.WriteLine ("Брой елементи в нов стек:" +

            newStack.Count ());

            Console.ReadKey ();

        }

    }

Когато изпълнявате горната програма, ето как изходът трябва да се появи в прозореца на конзолата.

Както можете да видите на фигура 1, оригиналният неизменяем стек (съдържащ 10 елемента) е непроменен след извикване на метода Pop (). По-скоро се създава нов неизменяем стек с 9 елемента.

Неизменяемите колекции не предлагат конструктори, но можете да се възползвате от статичния фабричен метод, наречен Create, както е показано в кодовия фрагмент, даден по-долу.

var list = ImmutableList.Create (1, 2, 3, 4, 5);

Ако искате да добавите или премахнете елемент от тази колекция, ще бъде създаден нов неизменяем списък и оригиналният неизменяем списък ще остане непроменен.

Неизменността е избор на дизайн; това означава, че екземпляр от тип не може да бъде променен, след като е създаден. С изключение на неизменяемите стекове и неизменните опашки, всички неизменяеми колекции са базирани на AVL дървета. Следователно можете да вмъквате елементи във всяка позиция на колекцията, т.е. началото, средата или края, без да е необходимо да копирате дървото в неговата цялост.

Как да направите повече в C #:

  • Как да използвам анотации на данни в C #
  • Как да работите с GUID в C # 8
  • Кога да се използва абстрактен клас срещу интерфейс в C #
  • Как да работя с AutoMapper в C #
  • Как да използвам ламбда изрази в C #
  • Как да работя с Action, Func и Predicate делегати в C #
  • Как да работя с делегати в C #
  • Как да внедрите прост регистратор в C #
  • Как да работя с атрибути в C #
  • Как да работя с log4net в C #
  • Как да приложим шаблона за проектиране на хранилището в C #
  • Как да работя с отражение в C #
  • Как да работя с файлова система за наблюдение в C #
  • Как да извършите мързелива инициализация в C #
  • Как да работите с MSMQ в C #
  • Как да работя с методи за разширение в C #
  • Как да използваме ламбда изрази в C #
  • Кога да се използва летливата ключова дума в C #
  • Как да използвам ключовата дума yield в C #
  • Как да приложим полиморфизъм в C #
  • Как да изградите свой собствен планировчик на задачи в C #
  • Как да работя с RabbitMQ в C #
  • Как да работите с кортеж в C #
  • Проучване на виртуални и абстрактни методи в C #
  • Как да използваме Dapper ORM в C #
  • Как да използвам шаблона за дизайн на мухата в C #