Расширяет Строковый класс с помощью сбивающего с толку IsNullOrEmpty?

Вам здесь не нужен цикл, что вы можете сделать, взяв boolean установить значение true, если музыка играет, и false, если остановить просто, верно?

11
задан Jhonny D. Cano -Leftware- 26 April 2009 в 13:09
поделиться

11 ответов

Я лично не фанат этого. Самая большая проблема с методами расширения сейчас - это обнаруживаемость. Если вы не знаете, все методы, которые существуют в конкретном типе, невозможно взглянуть на вызов метода и знать, что это метод расширения. Поэтому я нахожу проблематичным делать что-либо с методом расширения, что было бы невозможно при обычном вызове метода. В противном случае вы будете путать разработчиков.

Следствие этой проблемы существует в C ++. В нескольких реализациях C ++ можно вызывать методы экземпляра по указателям NULL, если вы не касаетесь полей или виртуальных методов типа. Я работал с несколькими фрагментами кода, которые делают это преднамеренно и придают методам другое поведение, когда " this == NULL ". Это' довольно невыносимо работать.

Это не значит, что мне не нравятся методы расширения. Наоборот, я наслаждаюсь ими и часто ими пользуюсь. Но я думаю, что есть два важных правила, которым вы должны следовать при написании.

  • Рассматривайте фактическую реализацию метода так, как будто это просто еще один статический метод, потому что на самом деле это так. Например, выбрасывать ArgumentException вместо NullReference для нулевого значения this
  • Не позволяйте методу расширения выполнять трюки, которые не мог сделать обычный метод экземпляра

EDIT Ответ на комментарий Мехрдада

Проблема с Воспользовавшись этим, я не вижу в str.IsNullOrEmpty значительного функционального преимущества перед String.IsNullOrEmpty (str). Единственное преимущество, которое я вижу, состоит в том, что одному требуется меньше печатать, чем другому. То же самое можно сказать и о методах расширения в целом. Но в этом случае вы дополнительно изменяете то, как люди думают о ходе программы.

Если люди действительно хотят более короткой типизации, разве IsNullOrEmpty (str) не будет намного лучшим вариантом? Это однозначно и является самым коротким из всех. True C # сегодня не поддерживает такую ​​функцию. Но представьте себе, если бы в C # я мог сказать

using SomeNamespace.SomeStaticClass;

. ​​В результате этого все методы SomeStaticClass теперь находятся в глобальном пространстве имен и доступны для привязки. Кажется, это то, чего хотят люди, но они прикрепляют его к методу расширения, который я не большой поклонник.

t IsNullOrEmpty (str) будет намного лучшим вариантом? Это однозначно и является самым коротким из всех. True C # сегодня не поддерживает такую ​​функцию. Но представьте себе, если бы в C # я мог сказать

using SomeNamespace.SomeStaticClass;

. ​​В результате этого все методы SomeStaticClass теперь находятся в глобальном пространстве имен и доступны для привязки. Кажется, это то, чего хотят люди, но они прикрепляют его к методу расширения, который я не большой поклонник.

t IsNullOrEmpty (str) будет намного лучшим вариантом? Это однозначно и является самым коротким из всех. True C # сегодня не поддерживает такую ​​функцию. Но представьте себе, если бы в C # я мог сказать

using SomeNamespace.SomeStaticClass;

. ​​В результате этого все методы SomeStaticClass теперь находятся в глобальном пространстве имен и доступны для привязки. Кажется, это то, чего хотят люди, но они прикрепляют его к методу расширения, который я не большой поклонник.

6
ответ дан 3 December 2019 в 01:09
поделиться

Если я не ошибаюсь, каждый ответ здесь опровергает тот факт, что метод расширения может быть вызван для нулевого экземпляра, и из-за этого они не поддерживают, считают, что это хорошая идея.

Позвольте мне опровергнуть их аргументы.

Я ВСЕ ВЕРЮ, что вызов метода для объекта, который может быть нулевым, сбивает с толку. Дело в том, что мы проверяем нулевые значения только в определенных местах, а не в 100% случаев. Это означает, что есть процент времени, когда каждый вызов метода, который мы делаем, потенциально связан с нулевым объектом. Это понятно и приемлемо. Если бы это было не так, мы проверяли бы null перед каждым вызовом метода.

Итак, как это сбивает с толку, что конкретный вызов метода может происходить с нулевым объектом? Посмотрите на следующий код:

var bar = foo.DoSomethingResultingInBar();
Console.Writeline(bar.ToStringOr("[null]"));

Вы в замешательстве? Вы должны быть. Потому что вот реализация foo:

public Bar DoSomethingResultingInBar()
{
  return null; //LOL SUCKER!
}

Видите? Вы читаете пример кода, совсем не путаясь. Вы поняли, что потенциально foo будет возвращать ноль из вызова этого метода, а вызов ToStringOr для бара приведет к 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 равен нулю. Вам все еще приходится иметь дело с этой возможностью.

Смущают ли методы расширения? Только если ты их не понимаешь. И, честно говоря, То же самое можно сказать о ЛЮБОЙ части языка, от делегатов до лямбд.

19
ответ дан 3 December 2019 в 01:09
поделиться

Я думаю, что корень этой проблемы - то, что Джон Скит упомянул в списке вещей, которые он ненавидит на своем любимом языке (C #): C # не должен был импортировать все методы расширения в целом пространстве имен автоматически. Этот процесс следовало бы сделать более явно.

Мое личное мнение по этому конкретному вопросу заключается в том, что (поскольку мы ничего не можем с этим поделать) использовать метод расширения, если хотите. Я не говорю, что это не будет сбивать с толку, но этот факт о методах расширения (которые можно вызывать по ссылкам null ) является глобальным и не влияет только на String.IsNullOrEmpty , поэтому разработчики C # должны с ним ознакомиться.

Кстати,

8
ответ дан 3 December 2019 в 01:09
поделиться

Лично я бы не стал создавать расширение, которое делает что-то, что уже существует в платформе, если бы это не было значительным улучшением юзабилити. В данном случае я не думаю, что это так. Кроме того, если бы я создал расширение, я бы назвал его таким образом, чтобы уменьшить путаницу, а не увеличить ее. Опять же, я думаю, что этот случай не проходит этот тест.

Сказав все это, у меня есть расширение строки, которое проверяет не только, является ли строка пустой или пустой, но также и содержит ли она только пробел. Я называю это IsNothing . Вы можете найти его здесь .

4
ответ дан 3 December 2019 в 01:09
поделиться

Мне очень нравится этот подход КАК ДОЛГО, КАК метод дает понять, что он проверяет, что объект нулевой. ThrowIfNull, IsNull, IsNullOrEmpty и т. Д. Он очень удобочитаемый.

5
ответ дан 3 December 2019 в 01:09
поделиться

Я думаю, что расширение любого объекта с помощью вызова типа «IsNull» немного сбивает с толку, и его следует избегать, если это возможно.

Можно утверждать, что метод IsEmptyString может быть полезен для типа String, и потому, что вы обычно комбинируете это с проверкой на null, что IsNullOrEmpty может быть полезным, но я бы этого тоже избегал, потому что у строкового типа уже есть статический метод, который делает это, и я не уверен Вы экономите столько времени при наборе текста (максимум 5 символов).

0
ответ дан 3 December 2019 в 01:09
поделиться

Это не просто выглядит так, как будто вы вызываете метод с нулевой переменной. Вы / находитесь / вызываете метод с нулевой переменной, хотя и реализованный с помощью метода статического расширения. Я понятия не имел, что методы расширения (о которых я уже подозревал) поддерживали это. Это даже позволяет вам делать сумасшедшие вещи, такие как:

public static int PowerLength(this string obj)
{
return obj == null ? 0 : obj.Length;
}

С того места, где я стою сейчас, я бы классифицировал любое использование метода расширения для нулевой ссылки в , которое считается вредным .

1
ответ дан 3 December 2019 в 01:09
поделиться

Да, это будет сбивать с толку.

Я думаю, что каждый, кто знает о IsNullOrEmpty () , воспринимает его использование как вполне естественное. Таким образом, предложенный вами метод расширения не добавит больше читабельности.

Возможно, для кого-то новичка в .NET этот метод расширения будет проще иметь дело, но есть вероятность опасности , что она или он этого не делает понимать все аспекты методов расширения (например, вам нужно импортировать пространство имен и что оно может быть вызвано в null). Она / он может задаться вопросом, почему этот метод расширения не существует в другом проекте. В любом случае: даже если кто-то является новичком в .NET, синтаксис метода IsNullOrEmpty () может стать естественным довольно быстро. Также здесь преимущества методов расширения не превзойдут вызванную им путаницу.

Редактировать:

1
ответ дан 3 December 2019 в 01:09
поделиться

Давайте посмотрим на «за» и «против»:

  1. Более читабельно.

Да, немного, но улучшение читабельности перевешивается тем, что выглядит как вы вызываете метод экземпляра для чего-то, что не обязательно должно быть экземпляром. По сути, его легче читать, но труднее понять, поэтому улучшенная читаемость - это всего лишь иллюзия.

  1. Меньше печатания.

Да, но это на самом деле не сильный аргумент. Если набор текста является основной частью вашего программирования, вы просто не делаете что-то настолько сложное, чтобы вы могли развиваться как разработчик.

  1. Может сбивать с толку, потому что переменная yourString может быть нулевой, и она выглядит следующим образом вы выполняете метод для пустой переменной.

True (как упоминалось выше).

1
ответ дан 3 December 2019 в 01:09
поделиться

Вызов метода для переменной с нулевым значением обычно приводит к исключению NullReferenceException. IsNullOrEmpty () -Metod отклоняется от этого поведения таким образом, что это не предсказуемо при простом взгляде на код. Поэтому я бы посоветовал не использовать его, так как это создает путаницу, а польза от сохранения пары символов минимальна.

0
ответ дан 3 December 2019 в 01:09
поделиться

В общем, я согласен с тем, что методы расширения безопасны для вызова по пустому значению, если в их имени есть слово «нулевое» или что-то подобное. Таким образом, я понимаю, что они могут быть безопасными для вызова с нулем. Кроме того, они лучше документируют этот факт в своем заголовке комментария XML, поэтому я получаю эту информацию, когда нахожу курсор мыши на вызов.

0
ответ дан 3 December 2019 в 01:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: