Extension Methods — это по сути просто «синтаксический сахар», но его использование в некоторых случаях может сильно облегчить жизнь программисту. Известны ли кому-нибудь сценарии полезного использования extensions, скрытые фичи, трюки и тд и тп?
Самые полезные варианты использования Extension Methods (C#)
Новые ответы
Есть сайт, созданный специально для того что бы собрать в одном месте различные Extension methods. Находится тут: http://www.extensionmethod.net/
Если определить текстовые константы для тегов и атрибутов HTML и несколько extension-методов, которые работают с классом TagBuilder
, то можно получить систему написания HTML-структур в fluent-манере. Это особенно удобно применять в helper`ах ASP.NET MVC:
return Html.Tag.Img
.AddAttribute(Html.Attribute.Src, imageSource)
.AddAttribute(Html.Attribute.Alt, imageAltText)
.Render();
Вот несколько extension`ов из Mono.Rocks:
Повторение действия несколько раз:
6.Times (i => Console.WriteLine (i));
Удобная реализация циклов for с инкрементом и декрементом:
6.UpTo (12, i => Console.WriteLine (i));
12.DownTo (6, i => Console.WriteLine (i));
А вот цикл Step спервого взгляда выглядит абсолютно нечитабельным:
5.Step (9, 2, i => Console.WriteLine (i));
Без сигнатуры и не разберешься
public static void Step (this int self, int limit, int step, Action<int> action)
Выполнение действия над каждой из строк многострочного текста:
@"
one
two
three".EachLine (line => Console.WriteLine (line));
Преобразование строки в значение enum определенного типа:
"Bar".ToEnum<Foo>()
Создание строки пути к элементу файловой системы из нескольких составляющих — намного удобнее чем вкладывать Path.Combine в себя несколько раз:
var path = new [] {"/home", "jb", "sources"}.PathCombine ();
Получение атрибутов для типа. Фактически можно использовать не только для типа, но и для свойства/метода/поля и тд:
var attribute = typeof (Bar).GetCustomAttribute<FooAttribute> ();
var attributes = typeof (Bar).GetCustomAttributes<FooAttribute> ();
Еще один вариант для System.String. У String есть перегруженные методы TrimEnd() и TrimEnd(Char[]), позволяющий удалить все пробелы или символы, перечисленные в массиве. Но в случае, если необходимо удалить упорядоченную последовательность символов (читай строку) эти методы не работают.
Предлагается вот такой вариант:
public static string TrimEnd(this string sourceString, string trimString)
{
if (!sourceString.EndsWith(trimString))
return sourceString;
int trimLength = trimString.Length;
return sourceString.Remove(sourceString.Length - trimLength, trimLength);
}
Ну и, соответственно, пример использования:
StringBuilder sb = new StringBuilder();
sb.AppendLine("some string1");
sb.AppendLine("some string2");
sb.AppendLine("some string3");
string str = sb.ToString().TrimEnd(Environment.NewLine); // Удаляем последний перевод на новую строку
Если определить extensions для примитивных типов double, int и тд то можно интересно работать с единицами измерения и конвертацией:
var результатВМетрах = 5.Метров() + 7.Километров() + 18.Сантиметров();
PS Я не любитель называть методы русскими словами, просто так показалось нагляднее)
Когда нужно привести объект к какому-то типу только чтобы вызвать один метод, очень раздражает синтаксис cast`а — слишком много скобочек приходится набирать и конструкция не очень читабельна:
((SomeType) target).DoWork();
В этом случае спасет такой простой extension:
public static T As<T>(this object @object)
{
return (T) @object;
}
Теперь можно писать так:
target.As<SomeType>().DoWork();
Интересный способ форматирования строки. Extension:
public static string FormatWith(this string target, params object[] args)
{
return string.Format(CultureInfo.CurrentCulture, target, args);
}
Этот extension позволяет удобнее форматировать строки:
var formatted = "This {0} template for {1}".FormatWith("is", "strings");
Трюк замечен в коде Kigg.
Здоровский пример :)