TGViewer
Channel Public Channel
C# | Вопросы собесов

C# | Вопросы собесов

@easy_c_sharp

Сайт: https://easyoffer.ru/
Все каналы: t.me/+xGeAw6ckJ4liYzQy

Контакт для рекламы: @sendme_ads
Subscribers
5.01K
Photos
39
Videos
0
Links
1.5K

Showing posts older than #2211 · Back to latest

Older Posts 20 shown
Post #2210 741
🤔 Что такое контекст синхронизации?

"контекст синхронизации" (SynchronizationContext) — это класс, который предоставляет возможность управлять способом, которым операции переключаются обратно в основной поток или контекст для продолжения выполнения после асинхронной операции. Это важно для приложений с графическим пользовательским интерфейсом, таких как Windows Forms и WPF, где доступ к элементам пользовательского интерфейса разрешён только из основного потока.

🚩Как он работает

Абстрагирует модель синхронизации для различных сред выполнения. Например, в приложениях Windows Forms и WPF управление элементами UI должно происходить в главном потоке. SynchronizationContext предоставляет методы для отправки (Send) и постановки (Post) задач, которые должны выполняться в правильном контексте.
🟠Send
синхронно отправляет делегат на выполнение в контекст синхронизации.
🟠Post
асинхронно отправляет делегат на выполнение в контекст синхронизации.

🚩Применение SynchronizationContext

Используется для того, чтобы после асинхронной операции вернуться в правильный поток и безопасно обновить UI или выполнить код, который требует выполнения в определённом потоке.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
LoadDataAsync();
}

private async void LoadDataAsync()
{
string data = await GetDataAsync();
// Асинхронно получаем данные и обновляем UI
Dispatcher.Invoke(() => DisplayData(data));
}

private Task<string> GetDataAsync()
{
return Task.Run(() =>
{
// Имитация долгой операции
Thread.Sleep(5000);
return "Data loaded";
});
}

private void DisplayData(string data)
{
MyTextBox.Text = data;
}
}


🚩Зачем он нужен

🟠Безопасность потоков
Позволяет безопасно обращаться к элементам UI из асинхронных или вторичных потоков.
🟠Правильное управление потоками
Обеспечивает выполнение кода в контексте, для которого он предназначен, что особенно важно в многопоточных и сетевых приложениях.

Ставь 👍 и забирай 📚 Базу знаний
Post #2209 666
🤔 Что такое примитив синхронизации semaphore?

Семафор — это ограничитель доступа, который позволяет нескольким потокам одновременно использовать ресурс, но только в пределах установленного количества. Например, если доступно 3 слота — максимум 3 потока могут работать параллельно, остальные ждут.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Post #2207 731
🤔 Какие есть виды привязок данных и когда применяются?

Привязка данных (Data Binding) — это механизм, который позволяет автоматически синхронизировать данные между источником (например, моделью) и интерфейсом (например, элементами UI).

🚩Односторонняя привязка (One-Way Binding)

Данные идут только в одном направлении: из модели в UI.
- Для вывода данных, которые не должны изменяться пользователем
- Например, для отображения текущего времени
Пример в WPF
<TextBlock Text="{Binding UserName}" />


🚩Двусторонняя привязка (Two-Way Binding)

Данные синхронизируются в обе стороны: UI ↔️ Модель
- В формах ввода (например, TextBox), чтобы обновлять данные в модели
- Используется в MVVM
Пример в WPF
<TextBox Text="{Binding UserName, Mode=TwoWay}" />


🚩Привязка к событиям (Event Binding)

Позволяет связывать UI с методами обработки событий.
- Для обработки кнопок (Button.Click)
- В реактивных фреймворках (Blazor, WinForms)
Пример в Blazor
<button @onclick="IncrementCount">Добавить</button>

@code {
private int count = 0;
private void IncrementCount() => count++;
}


🚩Привязка к командам (Command Binding)

Используется в паттерне MVVM вместо событий
- В WPF и Xamarin
- Позволяет отделить логику от UI
Пример в WPF
<Button Content="Сохранить" Command="{Binding SaveCommand}" />


🚩Привязка к коллекциям (ItemsSource Binding)

Позволяет привязывать списки к элементам UI (ListBox, DataGrid)
- В списках, таблицах, дропдаунах
Пример в WPF
<ListBox ItemsSource="{Binding Users}" DisplayMemberPath="Name" />


Ставь 👍 и забирай 📚 Базу знаний
Post #2205 612
🤔 Что такое индексы, какие типы бывают, использовал ли их на практике?

Индексы в контексте баз данных — это структуры, которые помогают ускорить операции выборки данных, предоставляя быстрые пути к данным в таблицах. Виды индексов включают кластерные, некластерные, полнотекстовые и другие. Кластерные индексы определяют физический порядок хранения данных в таблице, в то время как некластерные индексы хранят только указатели на данные. Я использовал индексы на практике для улучшения производительности запросов в базах данных.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Post #2204 574
🤔 Какие методы есть в Action фильтре?

Используются для выполнения логики до и после выполнения метода действия контроллера. Они предоставляют механизм для выполнения кросс-секционных задач, таких как логирование, обработка исключений, валидация и т.д. Action фильтры реализуют интерфейс IActionFilter или IAsyncActionFilter.

🚩Методы в Action фильтре

🟠OnActionExecuting
Этот метод вызывается перед выполнением метода действия. Здесь можно добавить логику, которая будет выполняться до вызова действия, например, логирование или проверка условий.
public void OnActionExecuting(ActionExecutingContext context)
{
// Логика до выполнения действия
}


🟠OnActionExecuted
Этот метод вызывается после выполнения метода действия. Здесь можно добавить логику, которая будет выполняться после вызова действия, например, логирование результатов или модификация ответа.
public void OnActionExecuted(ActionExecutedContext context)
{
// Логика после выполнения действия
}


🟠OnActionExecutionAsync
Этот метод объединяет функциональность OnActionExecuting и OnActionExecuted в одном асинхронном методе. Здесь можно определить логику, которая будет выполняться как до, так и после выполнения метода действия.
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
// Логика до выполнения действия

var resultContext = await next();

// Логика после выполнения действия
}


🚩Реализации Action фильтра

Синхронный Action фильтр:
public class SampleActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// Логика до выполнения действия
Console.WriteLine("Before executing action");
}

public void OnActionExecuted(ActionExecutedContext context)
{
// Логика после выполнения действия
Console.WriteLine("After executing action");
}
}


Асинхронный Action фильтр:
public class SampleAsyncActionFilter : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
// Логика до выполнения действия
Console.WriteLine("Before executing action");

var resultContext = await next();

// Логика после выполнения действия
Console.WriteLine("After executing action");
}
}


🚩Применение Action фильтра

Action фильтр можно применять к контроллерам или действиям контроллера с помощью атрибута [ServiceFilter] или [TypeFilter]. Также его можно зарегистрировать глобально в Startup.cs.

Применение к контроллеру или действию:
[ServiceFilter(typeof(SampleActionFilter))]
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}


Глобальная регистрация:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(config =>
{
config.Filters.Add(typeof(SampleActionFilter));
});
}


Ставь 👍 и забирай 📚 Базу знаний
  • 👍 1
Post #2202 610
🤔 Почему требуется API между базой данных и клиентским приложением?

API (например, REST или GraphQL) обеспечивает прослойку между клиентом и базой данных, потому что:
1. Безопасность — база данных не должна быть напрямую доступна клиенту.
2. Инкапсуляция логики — в API можно реализовать бизнес-логику и валидации.
3. Гибкость — можно изменять структуру базы, не затрагивая клиента.
4. Масштабируемость — API может обрабатывать нагрузку, кешировать данные и распределять запросы.
5. Контроль доступа — через API проще реализовать авторизацию и аутентификацию.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Post #2200 572
🤔 Какие есть модификаторы доступа?

Есть модификаторы доступа, которые определяют, кто может использовать классы, методы и переменные. Они помогают скрыть внутренние детали кода и контролировать доступ к данным.

🚩Подробное объяснение с примерами

🟠`public` (Открытый доступ)
Открытый доступ означает, что элемент можно использовать везде.
public class Car
{
public string Model = "Tesla";
}

class Program
{
static void Main()
{
Car car = new Car();
Console.WriteLine(car.Model); // Доступ открыт
}
}


🟠`private` (Только внутри класса)
Самый закрытый модификатор. Поля и методы невидимы за пределами класса.
class Car
{
private string model = "Tesla";

private void PrintModel()
{
Console.WriteLine(model);
}
}

class Program
{
static void Main()
{
Car car = new Car();
// car.model = "BMW"; Ошибка! Поле `model` — private
// car.PrintModel(); Ошибка! Метод `PrintModel` — private
}
}


🟠`protected` (Доступен в наследниках)
Доступен только внутри класса и его наследников.
class Car
{
protected string Model = "Tesla";
}

class ElectricCar : Car
{
public void ShowModel()
{
Console.WriteLine(Model); // Можно, потому что наследуемый класс
}
}

class Program
{
static void Main()
{
ElectricCar eCar = new ElectricCar();
// eCar.Model Ошибка! Поле `Model` доступно только в наследниках
}
}


🟠`internal` (Только внутри проекта)
Элементы с internal можно использовать только внутри одной сборки (проекта).
internal class Engine
{
public void Start() => Console.WriteLine("Двигатель запущен");
}

class Program
{
static void Main()
{
Engine engine = new Engine();
engine.Start(); // Работает, потому что внутри того же проекта
}
}


🟠`protected internal` (В сборке и у наследников)
Этот модификатор разрешает доступ внутри сборки, а также в классах-наследниках за её пределами.
public class Car
{
protected internal string Model = "Tesla";
}

class ElectricCar : Car
{
public void ShowModel()
{
Console.WriteLine(Model); // Можно, потому что наследник
}
}


🟠`private protected` (Только в классе и наследниках из той же сборки)
Этот модификатор ещё жёстче, чем protected internal:
- Доступ внутри класса – да
- В наследниках – только внутри той же сборки
- В других проектах – нет доступа!
class Car
{
private protected string Model = "Tesla";
}

class ElectricCar : Car
{
public void ShowModel()
{
Console.WriteLine(Model); // Можно, потому что наследник в той же сборке
}
}

class Program
{
static void Main()
{
ElectricCar eCar = new ElectricCar();
// eCar.Model Ошибка! `Model` доступен только в наследниках из этой сборки
}
}


Ставь 👍 и забирай 📚 Базу знаний
  • 👍 1
Post #2198 656
🤔 Что помнишь об авторизации?

Авторизация в контексте веб-разработки и программирования — это процесс, который проверяет, имеет ли пользователь права на выполнение определенных действий или доступ к конкретным ресурсам. В C# и .NET, это может быть реализовано через различные механизмы, такие как ролевая модель доступа (Role-based Access Control - RBAC) или претензионное управление доступом (Claims-based Access Control).

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Post #2196 761
🤔 Про абстрактные классы, интерфейсы и в чем их разница и особенности?

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

🚩Абстрактный класс

Абстрактный класс — это класс, который не может быть создан напрямую (нельзя создать объект этого класса). Он может содержать как абстрактные методы (без реализации), так и методы с реализацией.
public abstract class Animal
{
public abstract void MakeSound(); // Абстрактный метод
public void Sleep() // Метод с реализацией
{
Console.WriteLine("Sleeping...");
}
}


Пример
public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("Bark!");
}
}


Использование
Animal myDog = new Dog();
myDog.MakeSound(); // Вывод: Bark!
myDog.Sleep(); // Вывод: Sleeping...


🚩Интерфейс

Интерфейс — это контракт, который определяет только сигнатуры методов, свойств, событий и индексаторов. Реализацию этих членов должен предоставить класс, который реализует интерфейс.
public interface IMovable
{
void Move();
int Speed { get; set; }
}


Пример
public class Car : IMovable
{
public int Speed { get; set; }

public void Move()
{
Console.WriteLine($"Moving at speed: {Speed}");
}
}


Использование
IMovable myCar = new Car { Speed = 60 };
myCar.Move(); // Вывод: Moving at speed: 60


Ставь 👍 и забирай 📚 Базу знаний
Post #2194 705
🤔 Что должен возвращать GetHashCode?

Метод GetHashCode должен возвращать целое число, которое уникально идентифицирует объект в контексте его текущего состояния. Объекты, равные по Equals, должны иметь одинаковые hash-коды, но разные объекты могут иметь одинаковый hash-код.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Post #2192 759
🤔 Какие тесты бывают?

🚩Виды

🟠Юнит-тесты
Предназначены для проверки отдельных компонентов или модулей приложения в изоляции. Они помогают убедиться, что отдельные функции или методы работают правильно.
Цель: Проверка логики отдельных методов или классов.
Инструменты: xUnit, NUnit, MSTest.
using Xunit;

public class CalculatorTests
{
[Fact]
public void Add_SimpleValues_ReturnsSum()
{
var calculator = new Calculator();
var result = calculator.Add(2, 3);
Assert.Equal(5, result);
}
}

public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
}


🟠Интеграционные тесты
Проверяют взаимодействие между различными компонентами системы, убеждаясь, что они корректно работают вместе.
Цель: Проверка взаимодействия между модулями.
Инструменты: xUnit, NUnit, MSTest, плюс дополнительные библиотеки для тестирования баз данных или HTTP-запросов.
using System.Net.Http;
using System.Threading.Tasks;
using Xunit;

public class IntegrationTests
{
private readonly HttpClient _client;

public IntegrationTests()
{
var appFactory = new CustomWebApplicationFactory<Startup>();
_client = appFactory.CreateClient();
}

[Fact]
public async Task Get_EndpointReturnsSuccessAndCorrectContentType()
{
var response = await _client.GetAsync("/api/values");
response.EnsureSuccessStatusCode();
Assert.Equal("application/json; charset=utf-8", response.Content.Headers.ContentType.ToString());
}
}


🟠Функциональные тесты
Проверяют, что приложение выполняет свои функции в соответствии с требованиями. Эти тесты проверяют конкретные сценарии использования.
Цель: Проверка функциональности приложения на уровне пользователя.
Инструменты: Selenium, Playwright, Cypress.
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using Xunit;

public class UiTests
{
[Fact]
public void LoadPage_CheckTitle()
{
using (IWebDriver driver = new ChromeDriver())
{
driver.Navigate().GoToUrl("https://example.com");
Assert.Equal("Example Domain", driver.Title);
}
}
}


🟠Системные тесты
Проверяют приложение в целом, включая взаимодействие с внешними системами и проверку всех требований.
Цель: Проверка всей системы в интегрированном виде.
Инструменты: JUnit, TestNG для Java, или те же инструменты, что и для функциональных тестов.

🟠Приемочные тесты
Проводятся для проверки, что приложение соответствует требованиям и готово к использованию клиентом или конечным пользователем.
Цель: Подтверждение соответствия приложения требованиям.
Инструменты: Cucumber, SpecFlow (для BDD).

🟠Регрессионные тесты
Проверяют, что недавние изменения в коде не нарушили существующую функциональность.
Цель: Убедиться, что новые изменения не привели к новым багам.
Инструменты: Все инструменты для юнит-тестирования и функционального тестирования.

🟠Нагрузочные тесты
Проверяют, как приложение ведет себя под нагрузкой, например, при большом количестве одновременных пользователей или операций.
Цель: Оценка производительности и устойчивости приложения под нагрузкой.
Инструменты: JMeter, Gatling, Apache Bench.

Ставь 👍 и забирай 📚 Базу знаний
Post #2190 697
🤔 Что такое стек?

Стек — это структура данных LIFO, где последний добавленный элемент извлекается первым, используется для вызовов функций и локальных переменных.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
  • 🔥 1
Post #2188 769
🤔 Какова концепция сборки мусора в С#?

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

🚩Основные концепции сборки мусора

🟠Управляемая куча (Managed Heap)

Управляемая куча — это область памяти, в которой размещаются объекты, созданные в управляемой среде .NET. Когда создается новый объект, память для него выделяется в управляемой куче.

🟠Корни (Roots)
Корни — это переменные и ссылки, которые являются начальными точками для сборки мусора. Они включают глобальные и статические переменные, локальные переменные в стеке, а также ссылки из регистров процессора.

🟠Алгоритм маркировки и сжатия (Mark-and-Compact)
GC использует алгоритм маркировки и сжатия для определения объектов, которые больше не используются. Сначала он помечает все доступные объекты (те, до которых можно добраться из корней), а затем удаляет все непомеченные объекты, освобождая их память.

🟠Поколения (Generations)
Память управляемой кучи разделена на три поколения: поколение 0, поколение 1 и поколение 2. Это позволяет оптимизировать процесс сборки мусора:
Поколение 0: Содержит новые объекты. Сборка мусора здесь происходит чаще всего, так как большинство объектов живут недолго.
Поколение 1: Содержит объекты, которые пережили одну сборку мусора.
Поколение 2: Содержит объекты, которые пережили несколько сборок мусора. Сборка мусора здесь происходит реже всего, так как такие объекты считаются долгоживущими.

🚩Этапы сборки мусора

🟠Инициализация сборки мусора
Когда выделяется новая память и управляемая куча достигает определенного порога, запускается процесс сборки мусора.

🟠Маркировка (Mark)
GC проходит по всем корням и помечает все объекты, которые могут быть достигнуты.

🟠Удаление (Sweep)
После маркировки все непомеченные объекты считаются недоступными и могут быть удалены.

🟠Сжатие (Compact)
Для улучшения производительности и уменьшения фрагментации памяти, сборщик мусора может переместить оставшиеся объекты, чтобы освободить блоки памяти.

class Program
{
static void Main()
{
for (int i = 0; i < 1000; i++)
{
CreateObject();
}

// Явный вызов сборщика мусора (не рекомендуется для обычного использования)
GC.Collect();
}

static void CreateObject()
{
MyClass obj = new MyClass();
// Объект obj будет собран сборщиком мусора, когда он больше не будет использоваться
}
}

class MyClass
{
// Поля и методы класса
}


Ставь 👍 и забирай 📚 Базу знаний
Post #2186 689
🤔 Что такое middleware в ASP.NET core?

Middleware — это компоненты, которые обрабатывают HTTP-запросы и ответы в ASP.NET Core. Каждый компонент middleware может либо обработать запрос, либо передать его следующему компоненту в конвейере. Они используются для выполнения задач, таких как аутентификация, логирование или обработка ошибок. Последовательность middleware определяет поведение приложения и порядок обработки запросов.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
  • 🔥 1
Post #2184 691
🤔 Если в двух переменных хранится одинаковое значение, то будут ли они равны?

Сравнение значений переменных может зависеть от типа данных, хранящихся в этих переменных, и от способа их сравнения.

🟠Примитивные типы (Value Types)
Для примитивных типов (например, int, float, char, bool) значение хранятся непосредственно в переменных, и их сравнение выполняется по значению.
int a = 5;
int b = 5;

bool areEqual = (a == b); // True


🟠Ссылочные типы (Reference Types)
Для ссылочных типов (например, классы, строки) переменные содержат ссылки на объекты в куче. Сравнение ссылочных типов по умолчанию выполняется по ссылке, а не по значению.
class Person
{
public string Name { get; set; }
}

Person person1 = new Person { Name = "Alice" };
Person person2 = new Person { Name = "Alice" };

bool areEqual = (person1 == person2); // False, потому что сравниваются ссылки


🟠Строки (Strings)
Строки являются ссылочными типами, но переопределяют операторы сравнения == и Equals для сравнения по значению.
string str1 = "Hello";
string str2 = "Hello";

bool areEqual = (str1 == str2); // True, строки сравниваются по значению


🟠Кастомные классы
Для кастомных классов можно переопределить методы Equals и GetHashCode, чтобы сравнивать объекты по значению.
class Person
{
public string Name { get; set; }

public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
return false;

Person other = (Person)obj;
return Name == other.Name;
}

public override int GetHashCode()
{
return Name.GetHashCode();
}
}

Person person1 = new Person { Name = "Alice" };
Person person2 = new Person { Name = "Alice" };

bool areEqual = person1.Equals(person2); // True


Ставь 👍 и забирай 📚 Базу знаний
  • 👍 1
Post #2182 702
🤔 Принципы ООП?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Post #2180 655
🤔 Что такое примитив синхронзиации semaphore?

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

🚩Как работает семафор?

Семафор использует счётчик для отслеживания доступных "разрешений":
Когда поток запрашивает доступ к ресурсу, семафор уменьшает счётчик.
Если счётчик больше нуля, поток получает доступ.
Если счётчик равен нулю, поток блокируется, пока другой поток не освободит ресурс (увеличив счётчик).

🚩Пример использования `SemaphoreSlim`

В .NET часто используется SemaphoreSlim, так как он более лёгкий и эффективный, чем Semaphore.
using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
static SemaphoreSlim semaphore = new SemaphoreSlim(2); // Разрешаем максимум 2 потока одновременно

static async Task AccessResource(int id)
{
Console.WriteLine($"Поток {id} ждёт доступа...");
await semaphore.WaitAsync(); // Захватываем семафор
try
{
Console.WriteLine($"Поток {id} получил доступ!");
await Task.Delay(2000); // Имитация работы с ресурсом
}
finally
{
Console.WriteLine($"Поток {id} освобождает ресурс.");
semaphore.Release(); // Освобождаем семафор
}
}

static async Task Main()
{
Task[] tasks = new Task[5];
for (int i = 0; i < 5; i++)
{
tasks[i] = AccessResource(i);
}
await Task.WhenAll(tasks);
}
}


🚩Обычный `Semaphore`

Если нужна синхронизация между разными процессами, можно использовать Semaphore
Semaphore semaphore = new Semaphore(2, 2, "MyGlobalSemaphore");


Ставь 👍 и забирай 📚 Базу знаний
Post #2178 651
🤔 Какие есть подходы формирования БД?

1. Code First — структура БД создается из кода (классов).
2. Database First — сначала создается БД, затем генерируются модели.
3. Model First — создается визуальная модель, из неё генерируются и БД, и код.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Post #2176 746
🤔 Что такое медиатор?

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

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

1⃣
Определение интерфейса медиатора
public interface IMediator
{
void Notify(object sender, string ev);
}


2⃣Реализация медиатора
public class DialogMediator : IMediator
{
private Button _button;
private TextBox _textBox;

public DialogMediator(Button button, TextBox textBox)
{
_button = button;
_button.SetMediator(this);
_textBox = textBox;
_textBox.SetMediator(this);
}

public void Notify(object sender, string ev)
{
if (ev == "ButtonClick")
{
_textBox.Clear();
}
else if (ev == "TextBoxEnter")
{
_button.SetEnabled(true);
}
}
}


3⃣Компоненты, взаимодействующие через медиатора
public class Button
{
private IMediator _mediator;

public void SetMediator(IMediator mediator)
{
_mediator = mediator;
}

public void Click()
{
Console.WriteLine("Button clicked");
_mediator.Notify(this, "ButtonClick");
}

public void SetEnabled(bool enabled)
{
Console.WriteLine($"Button is {(enabled ? "enabled" : "disabled")}");
}
}

public class TextBox
{
private IMediator _mediator;

public void SetMediator(IMediator mediator)
{
_mediator = mediator;
}

public void EnterText()
{
Console.WriteLine("Text entered");
_mediator.Notify(this, "TextBoxEnter");
}

public void Clear()
{
Console.WriteLine("TextBox cleared");
}
}


4⃣Использование медиатора в приложении
var button = new Button();
var textBox = new TextBox();
var mediator = new DialogMediator(button, textBox);

textBox.EnterText(); // Ввод текста активирует кнопку
button.Click(); // Нажатие кнопки очищает текстовое поле


🚩Плюсы и минусы

➕Снижение связанности
Компоненты не взаимодействуют напрямую, а используют медиатор.
➕Упрощение поддержки
Вся логика взаимодействия сосредоточена в одном месте.
➕Повышение модульности
Легко добавлять новые компоненты или изменять существующие.
➖Усложнение медиатора
Медиатор может стать сложным, если в него добавляется много логики.
➖Единая точка отказа
Если медиатор выходит из строя, это может повлиять на всю систему.

Ставь 👍 и забирай 📚 Базу знаний
Older posts →
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →