Да, можно!
По умолчанию значимые типы (структуры,
int, double) передаются по значению. Но их можно передать по ссылке с помощью
ref или out. Копия передаётся в метод, а оригинал не меняется.
void ChangeValue(int number)
{
number = 10; // Изменится только копия
}
int x = 5;
ChangeValue(x);
Console.WriteLine(x); // 5 (значение не изменилось)
Позволяет менять оригинальную переменную.
void ChangeValue(ref int number)
{
number = 10; // Меняем оригинальное значение
}
int x = 5;
ChangeValue(ref x);
Console.WriteLine(x); // 10 (значение изменилось)
out тоже передаёт по ссылке, но требует обязательного присвоения внутри метода.void InitializeValue(out int number)
{
number = 100; // Обязательно присваиваем значение
}
int x;
InitializeValue(out x);
Console.WriteLine(x); // 100
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🤔1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
В C# ключевые слова
ref и out используются для передачи аргументов по ссылке, что позволяет методам изменять значения этих аргументов. Эти механизмы полезны как для значимых типов (структур), так и для ссылочных типов (объектов). Давайте рассмотрим более детально, зачем и как их используют для ссылочных типов.С помощью
ref можно передавать ссылочные типы таким образом, чтобы метод мог изменять саму ссылку, то есть ссылаться на другой объект.Ключевое слово
out позволяет передавать аргумент, который не обязательно должен быть инициализирован до вызова метода. Метод, принимающий out аргумент, обязан присвоить ему значение до завершения работы.Пример использования
ref class Program
{
static void ChangeReference(ref MyClass obj)
{
obj = new MyClass { Value = 20 };
}
static void Main()
{
MyClass myObj = new MyClass { Value = 10 };
ChangeReference(ref myObj);
Console.WriteLine(myObj.Value); // Output: 20
}
}
class MyClass
{
public int Value { get; set; }
}
Пример использования
out class Program
{
static void InitializeObject(out MyClass obj)
{
obj = new MyClass { Value = 30 };
}
static void Main()
{
MyClass myObj;
InitializeObject(out myObj);
Console.WriteLine(myObj.Value); // Output: 30
}
}
class MyClass
{
public int Value { get; set; }
}
ref и out добавляют гибкости при работе с методами, позволяя им изменять ссылки на объекты или создавать и возвращать новые объекты.Эти механизмы могут быть полезны для оптимизации, когда необходимо избежать лишнего копирования данных, особенно при работе с большими объектами.
out полезен для методов, которые должны вернуть несколько значений или инициализировать объекты, которые не могут быть инициализированы заранее.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊1
Использование контейнеров, таких как Docker, в .NET приложениях имеет множество преимуществ, но также и некоторые недостатки. Вот основные из них:
Контейнеры включают все необходимые зависимости и настройки, что позволяет легко переносить приложения между различными средами (разработка, тестирование, производство) без изменения кода.
Пример: Docker-образ, созданный на локальной машине разработчика, может быть запущен на сервере производства без изменений.
Контейнеры изолируют приложения и их зависимости, предотвращая конфликты между различными версиями библиотек и инструментов.
Пример: Разные версии .NET Core могут сосуществовать на одной машине в разных контейнерах.
Контейнеры легко масштабировать горизонтально, создавая новые экземпляры приложения в ответ на увеличивающуюся нагрузку.
Пример: В Kubernetes можно легко добавить новые поды с контейнерами, чтобы справиться с повышенной нагрузкой.
Контейнеры запускаются быстрее, чем виртуальные машины, так как они не требуют загрузки всей операционной системы.
Пример: Docker-контейнер может быть запущен за несколько секунд, тогда как виртуальная машина может загружаться несколько минут.
Контейнеры обеспечивают консистентность среды между разработкой, тестированием и продакшн-окружением.
Пример: Одинаковая версия .NET Runtime и конфигурации могут быть гарантированы во всех средах.
Контейнеры интегрируются с инструментами CI/CD, что упрощает автоматизацию сборки, тестирования и развертывания.
Пример: Jenkins или GitHub Actions могут использовать Docker для создания и тестирования приложений в изолированных средах.
Понимание и настройка контейнеров и связанных инструментов требует времени и навыков.
Пример: Изучение Docker, Docker Compose и Kubernetes может занять значительное время для команды.
Хотя контейнеры легче, чем виртуальные машины, они все равно добавляют некоторую накладную на производительность.
Пример: Контейнеры могут использовать больше ресурсов, чем напрямую запущенные на хосте процессы, особенно при интенсивных I/O операциях.
Контейнеры изолируют процессы, но изоляция не так сильна, как у виртуальных машин. Ошибки конфигурации могут привести к проблемам безопасности.
Пример: Уязвимость в Docker или неправильная конфигурация сетевых правил могут привести к компрометации контейнера.
Контейнеры зависят от хост-операционной системы и её ядра. Это может вызвать проблемы совместимости.
Пример: Windows-контейнеры не могут быть запущены на Linux-системах и наоборот.
Контейнеры лучше всего подходят для безгосударственных приложений. Управление состоянием и данными может быть сложным.
Пример: Работа с постоянными данными требует настройки volume'ов или использование внешних систем хранения данных.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2💊1
1. Adapter: преобразует интерфейс одного класса в интерфейс, который ожидает клиент; используется для интеграции несовместимых компонентов.
2. Decorator: добавляет новую функциональность существующему объекту без изменения его структуры.
3. Adapter изменяет совместимость, а Decorator — поведение объекта.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥1
Сборщик мусора (Garbage Collector, GC) — это форма автоматического управления памятью. Он отслеживает каждый объект, выделенный в куче, и определяет, какие объекты более не доступны для приложения, а затем освобождает память, занимаемую этими объектами. Это ключевой компонент во многих современных языках программирования и средах выполнения, облегчая задачу управления памятью.
Сборщик мусора периодически проходит через все объекты в куче, начиная с "корней" (объектов, непосредственно доступных в программе, например, через переменные в стеке вызовов и глобальные переменные). Он отмечает все объекты, до которых можно добраться напрямую или косвенно.
После маркировки доступных объектов, сборщик мусора удаляет все непомеченные объекты, освобождая ресурсы, которые они занимали.
Некоторые сборщики мусора перемещают оставшиеся объекты, чтобы уменьшить фрагментацию памяти и улучшить производительность работы с памятью.
Процесс сборки мусора может быть ресурсоёмким и может привести к заметным паузам в выполнении программы, особенно если куча большая.
Точное время сборки мусора может быть непредсказуемым, что может создавать проблемы в приложениях с реальным временем.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Entity Framework Core предлагает несколько стратегий работы с зависимостями и контекстом:
- Scoped контекст — создаётся на время одного запроса.
- Transient контекст — создаётся каждый раз заново.
- Singleton — крайне редко используется, так как контекст не потокобезопасен.
Также в EF Core есть несколько подходов к маппингу и конфигурации:
- Fluent API (в OnModelCreating)
- Аннотации атрибутов ([Key], [Required] и др.)
- Разделение конфигураций на отдельные классы (EntityTypeConfiguration)
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔8🔥2💊1
Interceptor (перехватчик) — это паттерн программирования, используемый для перехвата и обработки вызовов методов, запросов или событий перед их исполнением или после. В контексте C# и .NET, интерцепторы чаще всего применяются в:
ASP.NET Core Middleware — для перехвата HTTP-запросов.
Entity Framework Core Interceptors — для перехвата SQL-запросов и изменений данных.
Aspect-Oriented Programming (AOP) — для добавления кода перед или после выполнения метода.
можно записывать запросы, исключения, время выполнения.
проверка прав доступа перед выполнением запроса.
автоматическое управление транзакциями в базе данных.
например, автоматическая подмена аргументов.
можно сохранять результаты выполнения метода.
Entity Framework Core позволяет использовать интерцепторы для перехвата SQL-запросов. Это может быть полезно, например, для логирования всех SQL-запросов.
using Microsoft.EntityFrameworkCore.Diagnostics;
using System;
using System.Data.Common;
using System.Threading;
using System.Threading.Tasks;
public class SqlInterceptor : DbCommandInterceptor
{
public override InterceptionResult<DbDataReader> ReaderExecuting(
DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result)
{
Console.WriteLine($"SQL Query: {command.CommandText}");
return base.ReaderExecuting(command, eventData, result);
}
}
Теперь подключим этот интерцептор в DbContext
using Microsoft.EntityFrameworkCore;
public class MyDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.AddInterceptors(new SqlInterceptor());
base.OnConfiguring(optionsBuilder);
}
}
В ASP.NET Core интерцепторы можно реализовать через Middleware. Например, перехватим все HTTP-запросы и добавим в лог
public class RequestInterceptor
{
private readonly RequestDelegate _next;
public RequestInterceptor(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
Console.WriteLine($"HTTP Request: {context.Request.iss.onethod} {context.Request.Path}");
await _next(context);
}
}
Добавляем middleware в
Program.csvar builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseMiddleware<RequestInterceptor>();
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
app.Run();
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Конструкция using преобразуется в try-finally, чтобы гарантировать вызов Dispose().
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍2
В ASP.NET Core жизненный цикл запроса проходит несколько этапов — от получения HTTP-запроса до отправки ответа. В этом процессе участвуют Middleware, контроллеры, фильтры и обработчики событий.
Получение запроса (
HttpContext создаётся) Обработка через Middleware (передача запроса вниз)
Маршрутизация (Routing) — определение контроллера
Фильтры (например, аутентификация)
Вызов контроллера и метода (
Action) Обратный проход через Middleware (формирование ответа)
Отправка ответа клиенту
Middleware — это основной механизм обработки запросов.
Где регистрируются? → В
Program.cs (в app.Use...) Методы Middleware
app.Use(async (context, next) =>
{
Console.WriteLine("Перед обработкой запроса");
await next(); // Передаём запрос дальше
Console.WriteLine("После обработки запроса");
});
Контроллер обрабатывает запросы после маршрутизации.
Основные методы
public class HomeController : Controller
{
// Метод вызывается при GET-запросе
public IActionResult Index()
{
return View();
}
// Метод вызывается при POST-запросе
[HttpPost]
public IActionResult SubmitForm(FormModel model)
{
return RedirectToAction("Index");
}
}
Фильтры выполняются до и после вызова контроллера.
Методы фильтров
public class MyActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
Console.WriteLine("Перед вызовом метода контроллера");
}
public void OnActionExecuted(ActionExecutedContext context)
{
Console.WriteLine("После вызова метода контроллера");
}
}
В ASP.NET Core 6+ вся конфигурация находится в
Program.cs. Методы инициализации
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews(); // Подключаем MVC
var app = builder.Build();
app.UseRouting(); // Включаем маршрутизацию
app.UseAuthorization(); // Проверка прав
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers(); // Подключаем контроллеры
});
app.Run();
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
join в LINQ или SQL объединяет данные из двух коллекций или таблиц на основе общего поля. Например, в SQL это выполняется через сравнение ключей, указанных в ON, а в LINQ — с помощью метода Join. Результат может быть внутренним (INNER JOIN), внешним (LEFT JOIN, RIGHT JOIN) или полным (FULL JOIN).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ключевое слово using используется в двух основных контекстах: для управления областью видимости объектов, реализующих интерфейс
IDisposable, и для включения пространств имён.Можно использовать для создания блока кода, внутри которого объекты, реализующие интерфейс
IDisposable, автоматически освобождаются по завершении блока. Это удобно для управления ресурсами, такими как файловые потоки, базы данных или другие ресурсы системы, которые требуют явного освобождения.using (StreamWriter writer = new StreamWriter("example.txt"))
{
writer.WriteLine("Hello, world!");
}
// Здесь объект writer уже автоматически закрыт и освобожден.Также используется для объявления пространств имен, которые будут использоваться в коде, позволяя обращаться к классам внутри этих пространств без полного указания их имён.
using System;
using System.IO;
using System.Text;
// Теперь можно использовать классы из System, System.IO и System.Text без полного указания имени.
Для включения статических классов, что позволяет обращаться к статическим членам класса напрямую без указания имени класса.
using static System.Console;
using static System.Math;
class Program
{
static void Main()
{
WriteLine(Sqrt(144)); // Использование метода WriteLine и Sqrt без указания классов Console и Math
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Mutex (мьютекс) — это механизм исключительного доступа. Он позволяет только одному потоку или процессу использовать ресурс в конкретный момент. Остальные ждут, пока мьютекс не освободится. Это полезно при межпоточном или межпроцессном взаимодействии.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
MVVM (Model-View-ViewModel) — это паттерн проектирования, который разделяет логику программы и интерфейс пользователя. Он широко используется в WPF, Xamarin, MAUI и Blazor.
ViewModel обновляет Model (через
Command и INotifyPropertyChanged). Model уведомляет ViewModel об изменениях.
View автоматически обновляется (через Data Binding).
Model (Модель)
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
ViewModel (Логика)
using System.ComponentModel;
using System.Runtime.CompilerServices;
public class PersonViewModel : INotifyPropertyChanged
{
private string _name;
public string Name
{
get => _name;
set { _name = value; OnPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
View (XAML)
<TextBox Text="{Binding Name, Mode=TwoWay}" />
<TextBlock Text="{Binding Name}" />Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍1
- MVVM (Model-View-ViewModel) — используется во фреймворках вроде WPF, Angular.
- MVC (Model-View-Controller) — в JavaScript-приложениях (например, с Backbone).
- Observer — реактивные библиотеки (RxJS).
- Strategy — динамическое поведение компонентов.
- Factory — динамическое создание UI-компонентов.
Back-end (на .NET):
- Repository — изолирует работу с базой данных.
- Unit of Work — объединяет операции изменения данных в одну транзакцию.
- Dependency Injection — внедрение зависимостей (широко используется в
- Factory Method — для создания объектов с гибкой конфигурацией.
- Adapter/Decorator — обёртки над внешними API или логикой.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔1
Позволяют определять конструкторы прямо в объявлении класса или структуры, что упрощает код и улучшает его читаемость.
public class Person(string name, int age)
{
public string Name { get; } = name;
public int Age { get; } = age;
}
Обеспечивает более удобный синтаксис для создания коллекций.
var numbers = [1, 2, 3, 4, 5];
Теперь можно задавать значения по умолчанию для auto-properties, что делает код более лаконичным.
public string Name { get; set; } = "Unknown";Позволяет использовать алиасы для пространств имен, улучшая читаемость кода.
using Text = System.Text;
Улучшены возможности для работы с лямбда-выражениями, делая их более гибкими и мощными.
Эти нововведения направлены на упрощение синтаксиса языка, улучшение читаемости и поддерживаемости кода, а также на повышение производительности и удобства разработки.
public class Program
{
public static void Main()
{
var person = new Person("John", 30);
Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
var numbers = [1, 2, 3, 4, 5];
numbers.ForEach(n => Console.WriteLine(n));
var name = new Name { Value = "Unknown" };
Console.WriteLine(name.Value);
}
}
public class Person(string name, int age)
{
public string Name { get; } = name;
public int Age { get; } = age;
}
public class Name
{
public string Value { get; set; } = "Default Name";
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
1. Code First:
- Сначала пишется модель в коде (Entity, классы).
- Потом генерируется схема БД.
- Гибкий, удобен для разработчиков.
2. Database First:
- Сначала создаётся база данных, таблицы, связи.
- Генерируются классы по схеме.
- Используется, когда БД уже существует или управляется отдельно.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
Dispose метод является частью паттерна управления ресурсами, известного как "Dispose Pattern". Этот метод реализуется в классах через интерфейс
IDisposable. Цель — явное освобождение неуправляемых ресурсов и, по желанию, управляемых ресурсов, прежде чем сборщик мусора освободит объект. Это важно для эффективного управления памятью и другими системными ресурсами.включают в себя ресурсы, которые не управляются средой CLR (Common Language Runtime), например, файловые дескрипторы, сетевые соединения или указатели на память, выделенную вне .NET среды.
это объекты .NET, которые занимают память и потенциально удерживают ссылки на неуправляемые ресурсы.
Должен освобождать все неуправляемые ресурсы, занимаемые объектом, а также должен иметь возможность освобождать управляемые ресурсы, если это необходимо. Как правило, управляемые ресурсы освобождаются сами сборщиком мусора, но если управляемый ресурс включает в себя неуправляемые ресурсы, тогда
Dispose может быть вызван для их явного освобождения.public class ResourceHolder : IDisposable
{
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Освобождение управляемых ресурсов
}
// Освобождение неуправляемых ресурсов
disposed = true;
}
}
~ResourceHolder()
{
Dispose(false);
}
}
Пример использования Dispose
using (var resource = new ResourceHolder())
{
// Использование ресурса
}
// Метод Dispose автоматически вызывается при выходе из блока using
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
- Dictionary — не потокобезопасен, может выдавать исключения при одновременном доступе из разных потоков.
- ConcurrentDictionary — потокобезопасная коллекция, позволяет безопасно читать и изменять данные в многопоточном окружении без внешней синхронизации.
Используется в системах, где возможны параллельные обращения к структуре.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
Это паттерн проектирования поведенческих шаблонов, который позволяет уменьшить связанность между объектами, обеспечивая взаимодействие через центральный объект-посредник. Медиатор упрощает коммуникацию между компонентами системы, делая ее более модульной и легкой для сопровождения.
public interface IMediator
{
void Notify(object sender, string ev);
}
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);
}
}
}
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");
}
}
var button = new Button();
var textBox = new TextBox();
var mediator = new DialogMediator(button, textBox);
textBox.EnterText(); // Ввод текста активирует кнопку
button.Click(); // Нажатие кнопки очищает текстовое поле
Компоненты не взаимодействуют напрямую, а используют медиатор.
Вся логика взаимодействия сосредоточена в одном месте.
Легко добавлять новые компоненты или изменять существующие.
Медиатор может стать сложным, если в него добавляется много логики.
Если медиатор выходит из строя, это может повлиять на всю систему.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1