Если я не ошибаюсь, каждый ответ здесь осуждает тот факт, что метод расширения может быть вызван для нулевого экземпляра, и из-за этого они не поддерживают, считают, что это хорошая идея.
Позвольте мне противостоять их аргументам.
Я не верю, что вызов метода для объекта, который может быть нулевым, сбивает с толку. Дело в том, что мы проверяем нули только в определенных местах, а не в 100% случаев. Это означает, что есть процент времени, когда каждый вызов метода, который мы делаем, потенциально находится на нулевом объекте. Это понятно и приемлемо. Если это не так, мы будем проверять нулевое значение перед каждым вызовом метода.
Итак, как это сбивает с толку то, что конкретный вызов метода может происходить с нулевым объектом? Посмотрите на следующий код:
var bar = foo.DoSomethingResultingInBar();
Console.Writeline(bar.ToStringOr("[null]"));
Вы в замешательстве? Вы должны быть. Потому что вот реализация foo:
public Bar DoSomethingResultingInBar()
{
return null; //LOL SUCKER!
}
См? Вы читаете пример кода, совсем не путаясь. Вы понимали, что, возможно, foo вернет ноль из вызова этого метода, а вызов ToStringOr для bar
приведет к NRE. Твоя голова кружилась? Конечно, нет. Понял, что это может произойти. Теперь этот метод ToStringOr не знаком. Что вы делаете в этих ситуациях? Вы либо читаете документы по методу, либо изучаете код вызова. Вот оно:
public static class BarExtensions
{
public static string ToStringOr(this bar, string whenNull)
{
return bar == null ? whenNull ?? "[null]" : bar.ToString();
}
}
Смешение? Конечно, нет. Очевидно, что разработчику нужен сокращенный метод проверки, равен ли bar
ноль, и замены его ненулевой строкой. Это может значительно сократить ваш код и повысить читабельность и повторное использование кода. Конечно, вы можете сделать это другими способами, но этот способ не будет более запутанным, чем любой другой. Например:
var bar = foo.DoSomethingResultingInBar();
Console.Writeline(ToStringOr(bar, "[null]"));
Когда вы сталкиваетесь с этим кодом, что вы должны отличать от оригинальной версии? Вам все еще нужно изучить код, вы все равно должны определить его поведение, когда bar
равно нулю. Вы все еще должны иметь дело с этой возможностью.
Запутывают ли методы расширения? Только если ты их не понимаешь. И, честно говоря, то же самое можно сказать о ЛЮБОЙ части языка, от делегатов до лямбд.