C# | Вопросы собесов
5.11K subscribers
36 photos
1 file
997 links
Download Telegram
🤔 Что такое RESTful?

RESTful = соответствующий принципам REST.
Это не технология, а стиль построения API. RESTful API — это API, которое:
- Строится вокруг ресурсов.
- Использует HTTP-методы по назначению.
- Придерживается stateless взаимодействия.
- Предоставляет понятную структуру URL.
- Использует стандартизированные коды ответа.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥3
🤔 Что в себе может хранить делегат?

Делегат (delegate) — это указатель на метод(ы). Он может хранить:
1. Ссылку на один метод (одиночный делегат)
2. Ссылки на несколько методов (групповой делегат / multicast)
3. Анонимные методы и лямбда-выражения

🚩Делегат хранит ссылку на метод

Делегаты позволяют вызвать метод, даже если его имя заранее неизвестно.
Пример с одиночным делегатом
public delegate void MyDelegate(string message); // Объявляем делегат

public class Program
{
public static void ShowMessage(string msg) => Console.WriteLine($"Сообщение: {msg}");

public static void Main()
{
MyDelegate del = ShowMessage; // Делегат хранит ссылку на метод
del("Привет, делегаты!"); // Вызывает ShowMessage
}
}


🚩Делегат может хранить несколько методов (Multicast)

Делегаты можно связывать с несколькими методами с помощью +=. Пример группового делегата
public delegate void MyDelegate(string message);

public class Program
{
public static void Method1(string msg) => Console.WriteLine($"Метод 1: {msg}");
public static void Method2(string msg) => Console.WriteLine($"Метод 2: {msg}");

public static void Main()
{
MyDelegate del = Method1;
del += Method2; // Добавляем второй метод

del("Привет!");
// Выведет:
// Метод 1: Привет!
// Метод 2: Привет!
}
}


🚩Делегат может хранить анонимные методы и лямбды

Делегаты могут хранить "встроенные" методы (без отдельного определения).
Пример с анонимным методом
MyDelegate del = delegate (string msg) 
{
Console.WriteLine($"Анонимный метод: {msg}");
};
del("Привет!");


Пример с лямбда-выражением
MyDelegate del = msg => Console.WriteLine($"Лямбда: {msg}");
del("Привет!");


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Какие есть фазы очистки ресурсов?

Управление ресурсами в .NET делится на несколько этапов:
1. Finalize (финализатор):
- Позволяет объекту реагировать на удаление.
- Вызывается сборщиком мусора.
- Используется редко, потому что непредсказуем по времени.
2. Dispose:
- Ручной способ освободить управляемые и неуправляемые ресурсы.
- Используется через IDisposable.
- Можно вызывать через конструкцию try-with-resources (using).
3. GC.Collect():
- Принудительно запускает сборку мусора.
- Не рекомендуется использовать без нужды.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7💊2
🤔 В чем разница между FirstOfDefault и SingleOfDefault?

Методы FirstOrDefault и SingleOrDefault в LINQ используются для извлечения элементов из коллекции, но их логика работы отличается. Давайте разберем их подробно, с примерами.

🚩FirstOrDefault

FirstOrDefault возвращает первый элемент коллекции, который удовлетворяет условию (если условие указано), или первый элемент вообще, если условие отсутствует. Если в коллекции нет элементов, метод возвращает значение по умолчанию для типа (например, null для ссылочных типов или 0 для чисел).
Когда вас интересует первый элемент коллекции, но коллекция может быть пустой.
Когда вам неважно, есть ли другие элементы, соответствующие условию.
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

// Возьмем первый элемент, который больше 3
int result = numbers.FirstOrDefault(n => n > 3); // result = 4

// Если условие не выполняется
int result2 = numbers.FirstOrDefault(n => n > 10); // result2 = 0 (default для int)

// Если коллекция пустая
List<int> emptyList = new List<int>();
int result3 = emptyList.FirstOrDefault(); // result3 = 0


🚩SingleOrDefault
SingleOrDefault возвращает единственный элемент из коллекции, который удовлетворяет условию. Если такого элемента нет, метод возвращает значение по умолчанию. Однако если в коллекции есть более одного элемента, удовлетворяющего условию, будет выброшено исключение (InvalidOperationException).
Когда вы ожидаете, что в коллекции будет ровно один элемент, соответствующий условию.
Когда наличие нескольких подходящих элементов является ошибкой и вы хотите это обработать.
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

// Возьмем единственный элемент, равный 3
int result = numbers.SingleOrDefault(n => n == 3); // result = 3

// Если элемента, соответствующего условию, нет
int result2 = numbers.SingleOrDefault(n => n > 10); // result2 = 0

// Если элементов больше одного, возникает исключение
List<int> duplicateNumbers = new List<int> { 1, 2, 3, 3, 4 };
try
{
int result3 = duplicateNumbers.SingleOrDefault(n => n > 2);
}
catch (InvalidOperationException ex)
{
Console.WriteLine(ex.Message); // Ошибка: последовательность содержит несколько элементов
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Что такое DTO?

DTO (Data Transfer Object):
- Это простой класс, предназначенный только для передачи данных между слоями (например, между API и сервисом).
- Не содержит логики, только поля и свойства.
- Часто используется:
- при сериализации;
- в REST API;
- для защиты бизнес-модели от утечек наружу.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥1
🤔 Что такое I/O bound и CPU bound?

При выполнении программных задач можно выделить два типа нагрузок:

I/O-bound (ограничение ввода-вывода)
CPU-bound (ограничение процессора)

🚩I/O-bound (ограничение ввода-вывода)

Основная проблема: программа ждет завершения операций ввода-вывода (диска, сети, базы данных, файловой системы и т. д.), а не загружает процессор.
Примеры:
- Чтение и запись файлов на диск
- Запросы к базе данных
- HTTP-запросы к API
- Чтение данных из сети
Решение: Использование асинхронного программирования (async/await), чтобы не блокировать поток.
public async Task<string> FetchDataAsync()
{
using HttpClient client = new HttpClient();
return await client.GetStringAsync("https://example.com");
}


🚩CPU-bound (ограничение процессора)

Основная проблема: процессор сильно загружен вычислениями, и узким местом становится скорость обработки данных, а не ввод-вывод.
Примеры:
- Генерация больших отчетов
- Кодирование/декодирование видео
- Комплексные математические вычисления
- Сортировка больших массивов
public static long CalculateFactorial(int number)
{
return Enumerable.Range(1, number).Aggregate(1, (a, b) => a * b);
}

public async Task<long> ComputeAsync(int number)
{
return await Task.Run(() => CalculateFactorial(number));
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Что такое ООП?

ООП (Объектно-Ориентированное Программирование) — это парадигма программирования, основанная на концепции объектов, которые объединяют данные и методы для их обработки. Основные принципы ООП включают инкапсуляцию, наследование, полиморфизм и абстракцию. ООП позволяет моделировать реальный мир с помощью классов и объектов, улучшая структуру и повторное использование кода. В C# все программы строятся на основе классов, что делает его строго объектно-ориентированным языком.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🤔1
🤔 Какие бывают типы данных?

В C# существует множество различных типов данных, которые можно разделить на две основные категории: значимые типы (value types) и ссылочные типы (reference types). Рассмотрим каждую из этих категорий и их подтипы.

🚩Значимые типы (Value Types)

Значимые типы хранят данные непосредственно в своей памяти. Они обычно располагаются в стеке и имеют фиксированный размер. К значимым типам относятся:

🟠Простые типы (Simple Types)
Числовые типы
Целочисленные типы:
byte (8 бит)
sbyte (8 бит)
short (16 бит)
ushort (16 бит)
int (32 бита)
uint (32 бита)
long (64 бита)
ulong (64 бита)
Вещественные типы:
float (32 бита)
double (64 бита)
Десятичный тип:
decimal (128 бит)
Логический тип
bool (1 бит, значения true или false)
Символьный тип
char (16 бит, символы в формате Unicode)

🟠Структуры (Structs)
Пользовательские типы, которые могут содержать поля, свойства и методы. Пример: struct Point { public int X; public int Y; }

🟠Перечисления (Enums)
Специальные типы, представляющие набор именованных констант. Пример: enum Days { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday }

🟠Nullable Types
Типы, которые могут принимать значение null. Пример: int?, double?

🚩Ссылочные типы (Reference Types)

🟠Классы (Classes)
Основные объекты в C#, могут содержать поля, свойства, методы и события. Пример: class Person { public string Name; public int Age; }

🟠Интерфейсы (Interfaces)
Определяют контракт, который должны реализовать классы. Пример: interface IMovable { void Move(); }

🟠Массивы (Arrays)
Коллекции однотипных элементов. Пример: int[] numbers = new int[5];

🟠Делегаты (Delegates)
Типы, которые представляют собой ссылки на методы. Пример: delegate void Process(int value);

🟠Строки (Strings)
Непосредственно представляют собой последовательность символов. Пример: string message = "Hello, World!";

🟠Записи (Records)
Новый тип в C# 9.0, предназначенный для неизменяемых объектов. Пример: record Person(string Name, int Age);

🚩Примеры и использование

Значимые типы
int a = 5;
float b = 3.14f;
bool isTrue = true;
char letter = 'A';


Ссылочные типы
string message = "Hello, World!";
Person person = new Person { Name = "Alice", Age = 30 };

int[] numbers = new int[] { 1, 2, 3, 4, 5 };


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Что такое инкапсуляция?

Инкапсуляция в объектно-ориентированном программировании — это механизм упаковки данных (переменных) и кода, работающего с данными (методов), в один объект и ограничение доступа к некоторым компонентам объекта, что способствует безопасности и упрощению интерфейса.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Если мы используем Ref & out, то становится ли эта структура ссылочным типом?

Нет, структура (struct) не становится ссылочным типом, даже если мы передаём её через ref или out. Однако, когда структура передаётся с ref или out, передаётся сама структура (по ссылке), а не её копия. Это позволяет изменять исходный объект напрямую, избегая копирования.

🚩Разница между обычной передачей и передачей через `ref`

Передача структуры без ref (по значению, копируется)
struct Point
{
public int X;
public int Y;
}

void ChangePoint(Point p)
{
p.X = 100;
}

Point myPoint = new Point { X = 10, Y = 20 };
ChangePoint(myPoint);

Console.WriteLine(myPoint.X); // 10 (НЕ изменилось, потому что была копия)


Передача структуры с ref (по ссылке, изменения сохраняются)
void ChangePointRef(ref Point p)
{
p.X = 100;
}

ChangePointRef(ref myPoint);

Console.WriteLine(myPoint.X); // 100 (значение изменилось)


🚩Что насчёт `out`?

out работает так же, как ref, но требует обязательной инициализации внутри метода.
void InitPoint(out Point p)
{
p = new Point { X = 50, Y = 50 }; // Обязательно присвоить значение
}

Point newPoint;
InitPoint(out newPoint);

Console.WriteLine(newPoint.X); // 50


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍4
🤔 В чём разница между списком и массивом?

1. Список (List): динамическая структура данных, которая может менять размер. Поддерживает методы для работы с элементами (добавление, удаление).
2. Массив: фиксированная структура данных, размер задаётся при создании. Более эффективен в использовании памяти, но менее гибок.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🤔 Что из себя представляет библиотека dependency injectuion?

Dependency Injection (DI) — это паттерн проектирования, который помогает управлять зависимостями в приложении, делая код более гибким, тестируемым и поддерживаемым. Библиотека DI предоставляет механизмы для внедрения зависимостей автоматически, без явного создания экземпляров объектов в коде.

🚩Зачем нужна библиотека DI?

Без DI мы часто создаем объекты внутри классов вручную, что приводит к жесткой связности (tight coupling). Это делает код менее гибким и сложным в тестировании. DI помогает:
Разделить зависимости: объекты получают зависимости извне, а не создают их самостоятельно.
Облегчить тестирование: можно подставлять мок-объекты вместо реальных зависимостей.
Сделать код более гибким: легко подменять реализации зависимостей.

🚩Как работает DI?

В .NET Core и .NET 5+ встроена своя Microsoft.Extensions.DependencyInjection, но можно использовать сторонние библиотеки, такие как Autofac, Ninject, Unity.
Регистрация зависимостей
Внедрение зависимостей
Жизненный цикл зависимостей

🚩Пример DI в C# (.NET Core)

Создадим интерфейс и его реализацию
public interface IMessageService  
{
void SendMessage(string message);
}

public class EmailService : IMessageService
{
public void SendMessage(string message)
{
Console.WriteLine($"Отправка Email: {message}");
}
}


Зарегистрируем зависимость в DI-контейнере
var serviceProvider = new ServiceCollection()  
.AddSingleton<IMessageService, EmailService>()
.BuildServiceProvider();


Получим зависимость через DI
var messageService = serviceProvider.GetService<IMessageService>();  
messageService.SendMessage("Привет, DI!");


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Как сделать миграцию методов?

Миграция методов подразумевает их перемещение или переработку между классами, что требует анализа текущей логики и всех мест, где методы используются. Следует обновить ссылки, провести рефакторинг кода и написать тесты для проверки функциональности после изменений. Это помогает минимизировать риски нарушения работы системы.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3🤔1💊1
🤔 Приведи пример паттерна строитель в С#

Паттерн "Строитель" (Builder) используется для пошагового создания сложных объектов. Он удобен, когда объект имеет много параметров и возможных конфигураций.

🚩Проблема без паттерна "Строитель"

Допустим, у нас есть класс Car, и мы хотим создавать машины с разными конфигурациями:
public class Car
{
public string Engine { get; set; }
public int Wheels { get; set; }
public bool HasSunroof { get; set; }

public override string ToString()
{
return $"Car: Engine={Engine}, Wheels={Wheels}, Sunroof={HasSunroof}";
}
}


Создавать объект через конструкторы или инициализаторы становится неудобно, если у нас много параметров:
var car1 = new Car { Engine = "V8", Wheels = 4, HasSunroof = true };
var car2 = new Car { Engine = "V6", Wheels = 4, HasSunroof = false };


🚩Решение с использованием паттерна "Строитель"

Сделаем пошаговый процесс сборки объекта с помощью паттерна "Строитель".
Шаг 1: Создаём интерфейс строителя
public interface ICarBuilder
{
ICarBuilder SetEngine(string engine);
ICarBuilder SetWheels(int wheels);
ICarBuilder SetSunroof(bool hasSunroof);
Car Build();
}


Шаг 2: Реализуем конкретного строителя
public class CarBuilder : ICarBuilder
{
private Car _car = new Car(); // Временный объект

public ICarBuilder SetEngine(string engine)
{
_car.Engine = engine;
return this; // Возвращаем самого себя для цепочки вызовов
}

public ICarBuilder SetWheels(int wheels)
{
_car.Wheels = wheels;
return this;
}

public ICarBuilder SetSunroof(bool hasSunroof)
{
_car.HasSunroof = hasSunroof;
return this;
}

public Car Build()
{
return _car; // Возвращаем готовый объект
}
}


Шаг 3: Используем строителя
class Program
{
static void Main()
{
ICarBuilder builder = new CarBuilder();

Car sportsCar = builder
.SetEngine("V8")
.SetWheels(4)
.SetSunroof(true)
.Build();

Car economyCar = builder
.SetEngine("V4")
.SetWheels(4)
.SetSunroof(false)
.Build();

Console.WriteLine(sportsCar);
Console.WriteLine(economyCar);
}
}


Вывод в консоли
Car: Engine=V8, Wheels=4, Sunroof=True
Car: Engine=V4, Wheels=4, Sunroof=False


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🤔1
🤔 Что такое .NET Standard?

Это спецификация API, поддерживаемых различными реализациями платформы .NET, такими как .NET Framework, .NET Core и Xamarin.
1. Обеспечивает совместимость между этими реализациями, позволяя разрабатывать общий код.
2. Разработчики могут писать библиотеки, работающие на разных версиях и платформах .NET.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Какие типы данных можно использовать у Dictionary в качестве ключа?

В C# ключ (TKey) в Dictionary<TKey, TValue> должен быть уникальным и поддерживать сравнение.
Лучше всего использовать неизменяемые (immutable) типы, такие как:
Примитивные типы (int, string, char, bool, Guid, enum)
Кортежи (Tuple, ValueTuple)
Неизменяемые структуры (struct, если переопределён Equals и GetHashCode)

🚩Какие типы подходят в качестве ключа?

Числовые типы (int, double, long)
var dict = new Dictionary<int, string>
{
{1, "Один"},
{2, "Два"}
};
Console.WriteLine(dict[1]); // Вывод: Один


string (лучший выбор)
var dict = new Dictionary<string, int>
{
{"apple", 10},
{"banana", 5}
};
Console.WriteLine(dict["apple"]); // 10


Guid (уникальные идентификаторы)
var dict = new Dictionary<Guid, string>
{
{Guid.NewGuid(), "User1"},
{Guid.NewGuid(), "User2"}
};


enum (хороший вариант)
enum Status { New, Processing, Completed }

var dict = new Dictionary<Status, string>
{
{Status.New, "Заказ создан"},
{Status.Processing, "Заказ в обработке"}
};


Можно использовать несколько значений в качестве ключа:
var dict = new Dictionary<(int, string), string>
{
{(1, "apple"), "Красное яблоко"},
{(2, "banana"), "Жёлтый банан"}
};
Console.WriteLine(dict[(1, "apple")]); // Красное яблоко


🚩Какие типы нельзя использовать в качестве ключа?

List<T> (и другие изменяемые коллекции)
var dict = new Dictionary<List<int>, string>(); // Ошибка при использовании в качестве ключа!


class, если не переопределён Equals и GetHashCode
class Person { public string Name; }
var dict = new Dictionary<Person, string>(); // Плохо!


Нужно переопределить Equals и GetHashCode
class Person
{
public string Name { get; }

public Person(string name) => Name = name;

public override bool Equals(object? obj)
{
return obj is Person other && Name == other.Name;
}

public override int GetHashCode() => Name.GetHashCode();
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3💊1
🤔 Какие есть плюсы и минусы у типа Lazy?

Плюсы:
- Отложенная инициализация — объект создаётся только при первом обращении.
- Повышение производительности, если объект может не понадобиться вовсе.
- Удобно для дорогостоящих операций или тяжелых зависимостей.
Минусы:
- Может усложнить отладку.
- Необходимость потокобезопасности, особенно при использовании Lazy<T> без параметров.
- Возможные задержки при первом обращении, если инициализация тяжёлая.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое делегаты и зачем они нужны?

Делегаты — это типы, которые безопасно инкапсулируют методы, подобно указателям на функции в других языках программирования, но с проверкой типов во время компиляции. Могут ссылаться на метод, который принимает параметры и возвращает значение. Они используются для реализации обратных вызовов и событий, а также для определения пользовательских операций, которые могут быть выполнены методом, принимаемым в качестве параметра.

🚩Зачем они нужны?

🟠Обратные вызовы (Callbacks)
Делегаты предоставляют механизм для передачи методов в качестве аргументов другим методам. Это полезно для реализации обратных вызовов, позволяя вызывать методы в ответ на определенные события или условия.

🟠События
Являются основой системы событий. Они позволяют определять события и подписываться на них. Когда событие происходит, вызываются делегаты, связанные с этим событием, что позволяет реагировать на изменения или действия пользователя.

🟠Параметризация методами
Позволяют создавать более гибкие и масштабируемые приложения, поскольку методы могут быть переданы и использованы динамически в различных контекстах.

🟠Асинхронное программирование
Используются для асинхронного программирования, позволяя выполнять задачи в фоновом режиме, не блокируя основной поток приложения.

public delegate int Operation(int x, int y);

public class Calculator
{
public int PerformOperation(int x, int y, Operation op)
{
return op(x, y);
}
}

class Program
{
static int Add(int x, int y)
{
return x + y;
}

static int Multiply(int x, int y)
{
return x * y;
}

static void Main()
{
Calculator calc = new Calculator();

// Создание делегата для метода Add и вызов через метод PerformOperation
Operation addOp = new Operation(Add);
int result = calc.PerformOperation(5, 6, addOp);
Console.WriteLine("Addition: " + result);

// Создание делегата для метода Multiply и вызов через метод PerformOperation
Operation mulOp = new Operation(Multiply);
result = calc.PerformOperation(5, 6, mulOp);
Console.WriteLine("Multiplication: " + result);
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое метод расширения?

Это статический метод, который добавляет новую функциональность к существующим классам без их изменения. Это позволяет улучшить читаемость и повторное использование кода.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Forwarded from easyoffer
Официальный релиз easyoffer 2.0 состоится уже в течение нескольких дней.

Напоминаю, что в честь релиза запускаем акцию.

Первые 500 покупателей получат:

🚀 Скидку 50% на PRO тариф на 1 год
🎁 Подарок ценностью 5000₽ для тех, кто подписан на этот канал

🔔 Подпишитесь на этот канал: https://t.iss.one/+b2fZN17A9OQ3ZmJi
В нем мы опубликуем сообщение о релизе в первую очередь
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Как сейчас делается Singleton?

В современном C# паттерн Singleton можно реализовать несколькими способами, каждый из которых имеет свои преимущества и предназначен для различных сценариев использования. Рассмотрим несколько распространенных подходов к реализации Singleton.

🟠Ленивый Singleton (Lazy Initialization)
Ленивый Singleton инициализируется при первом обращении. Это обеспечивает отложенную инициализацию объекта и гарантирует потокобезопасность.
public class Singleton
{
private static readonly Lazy<Singleton> lazyInstance = new Lazy<Singleton>(() => new Singleton());

public static Singleton Instance => lazyInstance.Value;

private Singleton()
{
// Приватный конструктор
}
}


🟠Потокобезопасный Singleton (Thread-safe)
Этот подход использует lock для обеспечения потокобезопасности при создании экземпляра.
public class Singleton
{
private static Singleton instance;
private static readonly object lockObj = new object();

private Singleton()
{
// Приватный конструктор
}

public static Singleton Instance
{
get
{
if (instance == null)
{
lock (lockObj)
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
}


Eager Initialization (Инициализация при загрузке)
Экземпляр Singleton создается при загрузке класса. Это гарантирует потокобезопасность за счет особенностей инициализации статических переменных в .NET.
public class Singleton
{
private static readonly Singleton instance = new Singleton();

public static Singleton Instance => instance;

private Singleton()
{
// Приватный конструктор
}
}


🟠Static Constructor (Статический конструктор)
Использование статического конструктора для инициализации Singleton.
public class Singleton
{
private static readonly Singleton instance;

static Singleton()
{
instance = new Singleton();
}

public static Singleton Instance => instance;

private Singleton()
{
// Приватный конструктор
}
}


Singleton с внедрением зависимостей (Dependency Injection)
В современных приложениях, особенно с использованием ASP.NET Core, Singleton часто регистрируется в контейнере внедрения зависимостей.
public class SingletonService
{
public void DoWork()
{
// Выполнение работы
}
}

// Регистрация в контейнере служб
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<SingletonService>();
}

// Использование в контроллере
public class MyController : ControllerBase
{
private readonly SingletonService _singletonService;

public MyController(SingletonService singletonService)
{
_singletonService = singletonService;
}

public IActionResult Index()
{
_singletonService.DoWork();
return Ok();
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1