🤔 В чём разница между списком и массивом?
1. Список (List): динамическая структура данных, которая может менять размер. Поддерживает методы для работы с элементами (добавление, удаление).
2. Массив: фиксированная структура данных, размер задаётся при создании. Более эффективен в использовании памяти, но менее гибок.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
2. Массив: фиксированная структура данных, размер задаётся при создании. Более эффективен в использовании памяти, но менее гибок.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Зачем нужны операторы?
Операторы в C# позволяют:
- Выполнять арифметические, логические и побитовые операции (+, -, &&, |, <<, ++).
- Сравнивать значения (==, !=, >, <).
- Управлять потоком исполнения (??, ?:, is, as, await).
- Создавать собственные операторы перегрузки (например, operator + для собственного класса).
Операторы — важная часть языка, они позволяют делать код лаконичным, выразительным и типобезопасным.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Операторы в C# позволяют:
- Выполнять арифметические, логические и побитовые операции (+, -, &&, |, <<, ++).
- Сравнивать значения (==, !=, >, <).
- Управлять потоком исполнения (??, ?:, is, as, await).
- Создавать собственные операторы перегрузки (например, operator + для собственного класса).
Операторы — важная часть языка, они позволяют делать код лаконичным, выразительным и типобезопасным.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Что такое ORM?
Это технология для работы с базами данных, преобразующая данные между объектами приложения и реляционной БД.
1. Упрощает выполнение CRUD-операций без написания SQL-запросов.
2. Примеры: Entity Framework, Hibernate, SQLAlchemy.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
1. Упрощает выполнение CRUD-операций без написания SQL-запросов.
2. Примеры: Entity Framework, Hibernate, SQLAlchemy.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Приведи пример паттерна строитель в С#
Паттерн "Строитель" (Builder) используется для пошагового создания сложных объектов. Он удобен, когда объект имеет много параметров и возможных конфигураций.
🚩Проблема без паттерна "Строитель"
Допустим, у нас есть класс
Создавать объект через конструкторы или инициализаторы становится неудобно, если у нас много параметров:
🚩Решение с использованием паттерна "Строитель"
Сделаем пошаговый процесс сборки объекта с помощью паттерна "Строитель".
Шаг 1: Создаём интерфейс строителя
Шаг 2: Реализуем конкретного строителя
Шаг 3: Используем строителя
Вывод в консоли
Ставь 👍 и забирай 📚 Базу знаний
Паттерн "Строитель" (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
Ставь 👍 и забирай 📚 Базу знаний
👍2
🤔 Действительно ли при вызове метода Add уже генерируется SQL-код?
Нет, при вызове метода Add SQL-код еще не генерируется. На этом этапе сущность просто добавляется в контекст, и ее состояние помечается как "добавленное". SQL-код формируется и выполняется только при вызове метода SaveChanges(), который анализирует все изменения и генерирует соответствующие SQL-запросы.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Нет, при вызове метода Add SQL-код еще не генерируется. На этом этапе сущность просто добавляется в контекст, и ее состояние помечается как "добавленное". SQL-код формируется и выполняется только при вызове метода SaveChanges(), который анализирует все изменения и генерирует соответствующие SQL-запросы.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Пример выполнения кода, когда возвращается объект интерфейса Iqueryable?
🚩Пример работы с `IQueryable<T>` на Entity Framework Core
Предположим, у нас есть сущность
Теперь создадим репозиторий, который возвращает
🚩Вызов метода и выполнение запроса
Запрос к базе данных выполнится только при материализации (
Ставь 👍 и забирай 📚 Базу знаний
IQueryable<T> — это интерфейс, который используется для отложенного выполнения запросов (deferred execution). Он позволяет строить SQL-запросы к базе данных или манипулировать данными в памяти, но сам запрос выполняется только в момент его итерации (ToList(), FirstOrDefault(), Count(), и т. д.).🚩Пример работы с `IQueryable<T>` на Entity Framework Core
Предположим, у нас есть сущность
Product и контекст базы данных AppDbContextpublic class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
public class AppDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("YourConnectionString");
}
}
Теперь создадим репозиторий, который возвращает
IQueryable<Product>public class ProductRepository
{
private readonly AppDbContext _context;
public ProductRepository(AppDbContext context)
{
_context = context;
}
public IQueryable<Product> GetProducts()
{
return _context.Products.Where(p => p.Price > 100);
// Запрос не выполняется здесь! Только формируется
}
}
🚩Вызов метода и выполнение запроса
Запрос к базе данных выполнится только при материализации (
ToList(), FirstOrDefault(), Count(), и т. д.).var repository = new ProductRepository(new AppDbContext());
// Создаём IQueryable-запрос
IQueryable<Product> query = repository.GetProducts();
// Добавляем дополнительное условие (запрос еще НЕ выполнен)
query = query.OrderBy(p => p.Name);
// Теперь выполняем запрос к БД
List<Product> products = query.ToList(); // SQL-запрос отправляется в базу
Ставь 👍 и забирай 📚 Базу знаний
🤔 Как оптимизировать ситуацию, когда к таблице много join?
1. Проверить необходимость всех join — убрать ненужные связи.
2. Использовать индексы — создать индексы на ключевых колонках.
3. Разделить запрос — разбить сложный запрос на несколько более простых.
4. Использовать denormalization — объединить часто используемые данные в одну таблицу.
5. Кэшировать данные — уменьшить нагрузку на базу данных.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
1. Проверить необходимость всех join — убрать ненужные связи.
2. Использовать индексы — создать индексы на ключевых колонках.
3. Разделить запрос — разбить сложный запрос на несколько более простых.
4. Использовать denormalization — объединить часто используемые данные в одну таблицу.
5. Кэшировать данные — уменьшить нагрузку на базу данных.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Можно ли передать строку в lock?
Можно, но не рекомендуется. Строки могут быть разделяемыми между разными частями программы, даже если они написаны одинаково. Это может привести к неожиданным блокировкам. Лучше использовать уникальные объекты, специально созданные для блокировки.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Можно, но не рекомендуется. Строки могут быть разделяемыми между разными частями программы, даже если они написаны одинаково. Это может привести к неожиданным блокировкам. Лучше использовать уникальные объекты, специально созданные для блокировки.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥2
🤔 Какая разница между private и protected методами?
- private — доступен только внутри текущего класса.
- protected — доступен внутри текущего класса и его наследников.
private обеспечивает максимальную инкапсуляцию, а protected позволяет наследникам переопределять поведение или использовать базовые методы.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
- private — доступен только внутри текущего класса.
- protected — доступен внутри текущего класса и его наследников.
private обеспечивает максимальную инкапсуляцию, а protected позволяет наследникам переопределять поведение или использовать базовые методы.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Что такое unsafe?
Используется для объявления небезопасного контекста кода, который позволяет выполнять низкоуровневые операции, такие как манипуляции с указателями. Эти операции обычно не разрешены в безопасном управляемом коде, но могут быть необходимы для взаимодействия с неуправляемым кодом, оптимизации производительности или доступа к определенным системным ресурсам.
🚩Характеристики
🟠Объявление небезопасного контекста
Чтобы использовать указатели и выполнять небезопасные операции, нужно объявить метод, блок кода или тип как
🟠Компиляция с поддержкой `unsafe`
Для компиляции кода с
1⃣Откройте свойства проекта.
2⃣Перейдите на вкладку "Сборка".
3⃣Установите флажок "Разрешить небезопасный код".
🟠Использование указателей
Указатели позволяют напрямую работать с адресами памяти, что может быть полезно для некоторых оптимизаций или взаимодействия с низкоуровневым кодом, написанным на C или C++.
🟠Небезопасные структуры
Вы можете объявлять структуры с указателями и использовать их в небезопасном контексте.
🟠Стековые указатели (stackalloc)
🟠Взаимодействие с неуправляемым кодом
Небезопасный код часто используется для взаимодействия с API, написанными на других языках, такими как C или C++.
🚩Плюсы
➕Производительность
Позволяет выполнять высокоэффективные операции с памятью.
➕Взаимодействие с неуправляемым кодом
Необходим для вызова функций из библиотек, написанных на других языках.
➕Низкоуровневый контроль
Предоставляет возможность прямого управления памятью и аппаратными ресурсами.
Ставь 👍 и забирай 📚 Базу знаний
Используется для объявления небезопасного контекста кода, который позволяет выполнять низкоуровневые операции, такие как манипуляции с указателями. Эти операции обычно не разрешены в безопасном управляемом коде, но могут быть необходимы для взаимодействия с неуправляемым кодом, оптимизации производительности или доступа к определенным системным ресурсам.
🚩Характеристики
🟠Объявление небезопасного контекста
Чтобы использовать указатели и выполнять небезопасные операции, нужно объявить метод, блок кода или тип как
unsafe. unsafe void UnsafeMethod()
{
int a = 10;
int* p = &a; // Использование указателя
Console.WriteLine(*p); // Разыменование указателя
}
🟠Компиляция с поддержкой `unsafe`
Для компиляции кода с
unsafe необходимо включить поддержку небезопасного кода в настройках проекта. В Visual Studio это делается через свойства проекта:1⃣Откройте свойства проекта.
2⃣Перейдите на вкладку "Сборка".
3⃣Установите флажок "Разрешить небезопасный код".
🟠Использование указателей
Указатели позволяют напрямую работать с адресами памяти, что может быть полезно для некоторых оптимизаций или взаимодействия с низкоуровневым кодом, написанным на C или C++.
unsafe void PointerExample()
{
int a = 5;
int* p = &a; // p указывает на адрес переменной a
Console.WriteLine((int)p); // Вывод адреса переменной a
Console.WriteLine(*p); // Вывод значения переменной a через указатель
}
🟠Небезопасные структуры
Вы можете объявлять структуры с указателями и использовать их в небезопасном контексте.
unsafe struct UnsafeStruct
{
public int* Pointer;
}
🟠Стековые указатели (stackalloc)
stackalloc позволяет выделять память в стеке для массива в небезопасном контексте. Это может быть быстрее, чем выделение памяти в куче. unsafe void StackAllocExample()
{
int* array = stackalloc int[10]; // Выделение массива из 10 целых чисел в стеке
for (int i = 0; i < 10; i++)
{
array[i] = i;
}
}
🟠Взаимодействие с неуправляемым кодом
Небезопасный код часто используется для взаимодействия с API, написанными на других языках, такими как C или C++.
[DllImport("user32.dll")]
extern static unsafe int MessageBox(IntPtr hWnd, char* text, char* caption, int options);
unsafe void CallUnmanagedCode()
{
char* text = "Hello, World!";
char* caption = "My Message Box";
MessageBox(IntPtr.Zero, text, caption, 0);
}🚩Плюсы
➕Производительность
Позволяет выполнять высокоэффективные операции с памятью.
➕Взаимодействие с неуправляемым кодом
Необходим для вызова функций из библиотек, написанных на других языках.
➕Низкоуровневый контроль
Предоставляет возможность прямого управления памятью и аппаратными ресурсами.
Ставь 👍 и забирай 📚 Базу знаний
👍3
🤔 Что такое предикат?
Это делегат, представляющий метод, который принимает один или несколько аргументов и возвращает логическое значение (
🚩Особенности
🟠Тип делегата
В C# предикат представлен делегатом
🟠Использование
Предикаты обычно используются в методах стандартных коллекций, таких как
🚩Пример использования предиката
Определение предиката
Использование предиката с методом коллекции
🚩Лямбда-выражения как предикаты
Лямбда-выражения часто используются для определения предикатов непосредственно в месте вызова метода. Это делает код более компактным и удобочитаемым.
Пример использования лямбда-выражений
🚩Сценарии использования предикатов
🟠Фильтрация коллекций
Предикаты используются для определения условий фильтрации элементов в коллекциях.
🟠Поиск элементов
Предикаты помогают находить элементы, соответствующие определенному условию.
🟠Удаление элементов
Предикаты используются для удаления элементов, соответствующих определенному условию.
Ставь 👍 и забирай 📚 Базу знаний
Это делегат, представляющий метод, который принимает один или несколько аргументов и возвращает логическое значение (
true или false). Предикаты часто используются для фильтрации коллекций, поиска элементов и других операций, связанных с условными проверками.🚩Особенности
🟠Тип делегата
В C# предикат представлен делегатом
Predicate<T>, который принимает один аргумент типа T и возвращает bool.🟠Использование
Предикаты обычно используются в методах стандартных коллекций, таких как
List<T>, для поиска, удаления и фильтрации элементов.🚩Пример использования предиката
Определение предиката
public static bool IsEven(int number)
{
return number % 2 == 0;
}
Использование предиката с методом коллекции
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
// Использование предиката для поиска первого четного числа
int firstEven = numbers.Find(IsEven);
Console.WriteLine("First even number: " + firstEven);
// Использование предиката для удаления всех четных чисел
numbers.RemoveAll(IsEven);
Console.WriteLine("Numbers after removing evens: " + string.Join(", ", numbers));
}
public static bool IsEven(int number)
{
return number % 2 == 0;
}
}
🚩Лямбда-выражения как предикаты
Лямбда-выражения часто используются для определения предикатов непосредственно в месте вызова метода. Это делает код более компактным и удобочитаемым.
Пример использования лямбда-выражений
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
// Использование лямбда-выражения для поиска первого четного числа
int firstEven = numbers.Find(n => n % 2 == 0);
Console.WriteLine("First even number: " + firstEven);
// Использование лямбда-выражения для удаления всех четных чисел
numbers.RemoveAll(n => n % 2 == 0);
Console.WriteLine("Numbers after removing evens: " + string.Join(", ", numbers));
}
}
🚩Сценарии использования предикатов
🟠Фильтрация коллекций
Предикаты используются для определения условий фильтрации элементов в коллекциях.
List<int> evenNumbers = numbers.FindAll(IsEven);
🟠Поиск элементов
Предикаты помогают находить элементы, соответствующие определенному условию.
int firstEven = numbers.Find(IsEven);
🟠Удаление элементов
Предикаты используются для удаления элементов, соответствующих определенному условию.
numbers.RemoveAll(IsEven);
Ставь 👍 и забирай 📚 Базу знаний
🤔 Чем отличается IQueryable от IEnumerable?
`IEnumerable` используется для перебора коллекции в памяти и поддерживает ленивую загрузку данных. `IQueryable` позволяет работать с данными на уровне источника данных, поддерживая отложенное выполнение запросов и возможность составления SQL-запросов для баз данных. `IQueryable` чаще используется в LINQ для работы с базами данных, а `IEnumerable` — для работы с коллекциями, уже загруженными в память. `IQueryable` может оптимизировать запросы, выполняя их на сервере базы данных.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍1🔥1
🤔 Что такое куки и где оно хранится в запросе?
Это небольшие фрагменты данных, которые веб-сайты сохраняют на устройствах пользователей для хранения информации о сессии и отслеживания состояния. Куки используются для различных целей, таких как аутентификация пользователей, хранение настроек и предпочтений, а также отслеживание активности пользователей на сайте.
🚩Основные свойства
🟠Имя (Name)
Уникальный идентификатор для каждого куки.
🟠Значение (Value)
Данные, которые хранит куки.
🟠Домен (Domain)
Домен, для которого куки действителен.
🟠Путь (Path)
Путь на сервере, для которого куки действителен.
🟠Время истечения (Expiration/Max-Age)
Дата или время, когда куки должен быть удален.
🟠Безопасность (Secure)
Указывает, что куки должны передаваться только через HTTPS.
🟠HTTPOnly
Указывает, что куки недоступен через JavaScript, только через HTTP(S) запросы.
🚩Где хранятся
🟠Установка куки с сервера (Set-Cookie)
Сервер отправляет куки в ответе на запрос клиента с использованием заголовка
🟠Отправка куки клиентом (Cookie)
Браузер автоматически добавляет соответствующие куки в заголовок
🚩Пример использования
Установка куки на сервере (пример на Node.js с использованием Express)
Доступ к куки на клиенте (пример на JavaScript)
🚩Важные моменты
🟠Безопасность
Куки с флагом
🟠Размер и количество
Обычно один куки не должен превышать 4KB, и на одном домене может быть установлено не более 20-30 куки.
🟠Конфиденциальность
Куки могут содержать чувствительные данные, поэтому важно защищать их и использовать шифрование, если необходимо.
Ставь 👍 и забирай 📚 Базу знаний
Это небольшие фрагменты данных, которые веб-сайты сохраняют на устройствах пользователей для хранения информации о сессии и отслеживания состояния. Куки используются для различных целей, таких как аутентификация пользователей, хранение настроек и предпочтений, а также отслеживание активности пользователей на сайте.
🚩Основные свойства
🟠Имя (Name)
Уникальный идентификатор для каждого куки.
🟠Значение (Value)
Данные, которые хранит куки.
🟠Домен (Domain)
Домен, для которого куки действителен.
🟠Путь (Path)
Путь на сервере, для которого куки действителен.
🟠Время истечения (Expiration/Max-Age)
Дата или время, когда куки должен быть удален.
🟠Безопасность (Secure)
Указывает, что куки должны передаваться только через HTTPS.
🟠HTTPOnly
Указывает, что куки недоступен через JavaScript, только через HTTP(S) запросы.
🚩Где хранятся
🟠Установка куки с сервера (Set-Cookie)
Сервер отправляет куки в ответе на запрос клиента с использованием заголовка
Set-Cookie. HTTP/1.1 200 OK
Set-Cookie: sessionId=abc123; Path=/; Expires=Wed, 09 Jun 2023 10:18:14 GMT
Content-Type: text/html
🟠Отправка куки клиентом (Cookie)
Браузер автоматически добавляет соответствующие куки в заголовок
Cookie при каждом последующем запросе к серверу, для которого эти куки действительны. GET /dashboard HTTP/1.1
Host: example.com
Cookie: sessionId=abc123
🚩Пример использования
Установка куки на сервере (пример на Node.js с использованием Express)
const express = require('express');
const app = express();
app.get('/', (req, res) => {
// Устанавливаем куки
res.cookie('sessionId', 'abc123', {
maxAge: 900000,
httpOnly: true
});
res.send('Куки установлены');
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});Доступ к куки на клиенте (пример на JavaScript)
// Установка куки
document.cookie = "username=JohnDoe; expires=Thu, 18 Dec 2023 12:00:00 UTC; path=/";
// Получение всех куки
let cookies = document.cookie;
console.log(cookies);
🚩Важные моменты
🟠Безопасность
Куки с флагом
Secure передаются только по HTTPS-соединениям. Куки с флагом HttpOnly недоступны через JavaScript, что помогает защитить их от XSS-атак.🟠Размер и количество
Обычно один куки не должен превышать 4KB, и на одном домене может быть установлено не более 20-30 куки.
🟠Конфиденциальность
Куки могут содержать чувствительные данные, поэтому важно защищать их и использовать шифрование, если необходимо.
Ставь 👍 и забирай 📚 Базу знаний
🤔 Какие есть подходы в рамках EF Core?
Entity Framework Core предлагает несколько стратегий работы с зависимостями и контекстом:
- Scoped контекст — создаётся на время одного запроса.
- Transient контекст — создаётся каждый раз заново.
- Singleton — крайне редко используется, так как контекст не потокобезопасен.
Также в EF Core есть несколько подходов к маппингу и конфигурации:
- Fluent API (в OnModelCreating)
- Аннотации атрибутов ([Key], [Required] и др.)
- Разделение конфигураций на отдельные классы (EntityTypeConfiguration)
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Entity Framework Core предлагает несколько стратегий работы с зависимостями и контекстом:
- Scoped контекст — создаётся на время одного запроса.
- Transient контекст — создаётся каждый раз заново.
- Singleton — крайне редко используется, так как контекст не потокобезопасен.
Также в EF Core есть несколько подходов к маппингу и конфигурации:
- Fluent API (в OnModelCreating)
- Аннотации атрибутов ([Key], [Required] и др.)
- Разделение конфигураций на отдельные классы (EntityTypeConfiguration)
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Что такое делегаты и зачем они нужны?
Делегаты — это типы, которые безопасно инкапсулируют методы, подобно указателям на функции в других языках программирования, но с проверкой типов во время компиляции. Могут ссылаться на метод, который принимает параметры и возвращает значение. Они используются для реализации обратных вызовов и событий, а также для определения пользовательских операций, которые могут быть выполнены методом, принимаемым в качестве параметра.
🚩Зачем они нужны?
🟠Обратные вызовы (Callbacks)
Делегаты предоставляют механизм для передачи методов в качестве аргументов другим методам. Это полезно для реализации обратных вызовов, позволяя вызывать методы в ответ на определенные события или условия.
🟠События
Являются основой системы событий. Они позволяют определять события и подписываться на них. Когда событие происходит, вызываются делегаты, связанные с этим событием, что позволяет реагировать на изменения или действия пользователя.
🟠Параметризация методами
Позволяют создавать более гибкие и масштабируемые приложения, поскольку методы могут быть переданы и использованы динамически в различных контекстах.
🟠Асинхронное программирование
Используются для асинхронного программирования, позволяя выполнять задачи в фоновом режиме, не блокируя основной поток приложения.
Ставь 👍 и забирай 📚 Базу знаний
Делегаты — это типы, которые безопасно инкапсулируют методы, подобно указателям на функции в других языках программирования, но с проверкой типов во время компиляции. Могут ссылаться на метод, который принимает параметры и возвращает значение. Они используются для реализации обратных вызовов и событий, а также для определения пользовательских операций, которые могут быть выполнены методом, принимаемым в качестве параметра.
🚩Зачем они нужны?
🟠Обратные вызовы (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);
}
}
Ставь 👍 и забирай 📚 Базу знаний