Методы расширения
Часть раздела Объектно-ориентированное программирование путешествия по C# на Coddy — урок 39 из 70.
Методы расширения позволяют добавлять новые методы к существующим типам без изменения их исходного кода или создания производных классов. Они выглядят так, как будто являются собственными методами типа, что делает ваш код более читаемым и интуитивно понятным.
Чтобы создать метод расширения, определите статический метод в статическом классе, в котором перед первым параметром стоит ключевое слово this:
public static class StringExtensions
{
public static int WordCount(this string str)
{
return str.Split(' ').Length;
}
}Теперь вы можете вызывать этот метод напрямую для любой строки:
string sentence = "Hello World Today";
int count = sentence.WordCount(); // 3Параметр this string str сообщает компилятору, что этот метод расширяет тип string. Когда вы вызываете sentence.WordCount(), компилятор преобразует это в StringExtensions.WordCount(sentence) за кулисами.
Методы расширения также могут принимать дополнительные параметры:
public static bool IsLongerThan(this string str, int length)
{
return str.Length > length;
}
// Использование
bool result = "Hello".IsLongerThan(3); // trueЭта техника широко используется в LINQ, где такие методы, как Where() и Select() являются методами расширения для IEnumerable. Методы расширения — это мощный инструмент для добавления вспомогательных функций к типам, которые вы не контролируете, что позволяет сохранять ваш код чистым и выразительным.
Задание
ЛегкоДавайте создадим набор полезных методов расширения для целых чисел, которые добавляют удобную функциональность, которую вы ожидали бы увидеть встроенной. Вы создадите статический класс, содержащий методы расширения, которые можно вызывать напрямую для любого целого числа, что сделает ваш код более выразительным и читаемым.
Вы организуете свой код в двух файлах:
IntExtensions.cs: Создайте статический класс с именемIntExtensionsв пространстве именUtilities. Этот класс будет содержать методы расширения, дополняющие типint:IsEven()— возвращаетtrue, если число четное, иfalseв противном случаеSquare()— возвращает число, умноженное на само себяIsInRange(int min, int max)— возвращаетtrue, если число находится между min и max (включительно), иfalseв противном случае
this, чтобы указать, какой тип вы расширяете.Program.cs: В основном файле считайте целое число из входных данных и продемонстрируйте работу всех трех методов расширения. Вызовите каждый метод непосредственно для целого числа, как если бы это был встроенный метод, а затем выведите результаты.
Вы получите три входных значения:
- Число для проверки (целое число)
- Минимальное значение для проверки диапазона (целое число)
- Максимальное значение для проверки диапазона (целое число)
Выведите результат в следующем формате:
Is {number} even? {True/False}
Square of {number}: {result}
Is {number} in range [{min}-{max}]? {True/False}Например, если входные данные — 7, 5 и 10, вывод должен быть следующим:
Is 7 even? False
Square of 7: 49
Is 7 in range [5-10]? TrueОбратите внимание, насколько естественно можно писать number.IsEven() и number.Square() — методы расширения ощущаются так, будто они всегда были частью типа integer!
Шпаргалка
Методы расширения позволяют добавлять новые методы к существующим типам без изменения их исходного кода. Они должны быть определены как статические методы в статическом классе, при этом перед первым параметром должно стоять ключевое слово this.
Базовый синтаксис метода расширения:
public static class StringExtensions
{
public static int WordCount(this string str)
{
return str.Split(' ').Length;
}
}Использование:
string sentence = "Hello World Today";
int count = sentence.WordCount(); // 3Ключевое слово this перед первым параметром указывает, какой тип расширяется. Компилятор преобразует sentence.WordCount() в StringExtensions.WordCount(sentence).
Методы расширения с дополнительными параметрами:
public static bool IsLongerThan(this string str, int length)
{
return str.Length > length;
}
bool result = "Hello".IsLongerThan(3); // trueПопробуйте сами
using System;
using Utilities;
class Program
{
public static void Main(string[] args)
{
// Чтение входных данных
int number = Convert.ToInt32(Console.ReadLine());
int min = Convert.ToInt32(Console.ReadLine());
int max = Convert.ToInt32(Console.ReadLine());
// TODO: Используйте методы расширения для 'number' и выведите результаты
// Вызовите number.IsEven(), number.Square() и number.IsInRange(min, max)
// Выведите в формате:
// Is {number} even? {True/False}
// Square of {number}: {result}
// Is {number} in range [{min}-{max}]? {True/False}
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыПространства имен и директивыВведение в классы и объектыКлючевое слово 'this'Методы и параметрыПоля и свойстваКонструкторыИнициализаторы объектовИтоги — Простой калькулятор4Наследование
Основы синтаксиса наследования (:)Ключевое слово 'base'Ключевые слова Virtual и OverrideЗапечатанные классыБазовый класс 'object'Итоги — Иерархия сотрудников7Продвинутые возможности
Перегрузка операторовИндексаторы (this[])Переопределение ToString()Методы расширенияПовторение — Пользовательский список10Паттерны проектирования. Часть 1
Введение в паттерны проектированияПотокобезопасный SingletonПаттерн FactoryПаттерн Observer (События)Паттерн Strategy13Финальные испытания
Платформа для онлайн-обученияКомпонент игрового персонажаСервис аренды транспорта2Свойства и статические члены
Автоматически реализуемые свойстваСвойства только для чтения и записиСтатические поля и методыСтатические классыЧлены в виде выражений5Полиморфизм и интерфейсы
Полиморфизм: компиляция vs выполнениеИнтерфейс vs абстрактный классМножественные интерфейсыЯвные интерфейсыUpcasting и DowncastingИтоги: Калькулятор фигур8Продвинутые концепции ООП
Композиция вместо наследованияGenerics (классы и методы)Делегаты и событияАтрибуты и рефлексияIDisposable и оператор usingОсновы Dependency Injection11Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн Компоновщик3Архитектура классов
Экземплярные и статические данныеКлючевые слова 'readonly' и 'const'Опорные поляПовторение — Менеджер банковских счетов6Инкапсуляция
Модификаторы доступаСвойства для инкапсуляцииРеализация скрытия данныхПаттерны неизменяемостиИтоги — Записи студентов9Переменное количество аргументов
Ключевое слово 'params'Необязательные параметрыИменованные аргументыПерегрузка методов