Ответ
В C# есть несколько основных паттернов и языковых средств для расширения функциональности классов:
-
Наследование (Inheritance) Классический способ создания иерархии "is-a". Новый класс наследует поля, свойства и методы базового, может их переопределять или добавлять новые.
public class Vehicle { public void StartEngine() { } } public class Car : Vehicle { public void EnableAirConditioning() { } } // Car IS-A Vehicle -
Композиция (Composition) Принцип "has-a". Поведение расширяется за счёт включения экземпляров других классов и делегирования им вызовов. Это часто более гибкая альтернатива наследованию.
public class Logger { public void Log(string msg) => Console.WriteLine(msg); } public class OrderProcessor { private readonly Logger _logger; // Композиция public OrderProcessor(Logger logger) { _logger = logger; } public void Process() { _logger.Log("Processing started..."); } } -
Методы расширения (Extension Methods) Позволяют добавлять методы к существующим типам (даже
sealedили из сторонних библиотек) без изменения их исходного кода или создания подкласса.public static class DateTimeExtensions { public static bool IsWeekend(this DateTime date) => date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday; } // Использование: bool isWeekend = DateTime.Now.IsWeekend(); -
Паттерн Декоратор (Decorator Pattern) Структурный паттерн, который динамически добавляет объекту новую функциональность, оборачивая его в другой объект с тем же интерфейсом.
public interface INotifier { void Send(string message); } public class EmailNotifier : INotifier { public void Send(string msg) => Console.WriteLine($"Email: {msg}"); } public class SmsNotifierDecorator : INotifier { private readonly INotifier _wrappedNotifier; public SmsNotifierDecorator(INotifier notifier) { _wrappedNotifier = notifier; } public void Send(string msg) { _wrappedNotifier.Send(msg); // Базовая функциональность Console.WriteLine($"SMS: {msg}"); // Добавленная функциональность } } -
Частичные классы (Partial Classes) Позволяют разделить определение одного класса на несколько файлов. Часто используется в сгенерированном коде (например, WinForms, WPF), чтобы отделить пользовательскую логику от автоматически генерируемой.
// Файл: MyClass.Generated.cs (автосгенерирован) public partial class MyClass { public int Id { get; set; } } // Файл: MyClass.Custom.cs (ручная разработка) public partial class MyClass { public string GetDisplayName() => $"ID: {Id}"; }
Выбор подхода зависит от контекста: наследование для иерархий типов, композиция для гибкости, методы расширения для утилитарных функций, декоратор для динамического добавления обязанностей.