Почему myString.IsNullOrEmpty() не встроен в .Net? - программирование

Почему myString.IsNullOrEmpty() не встроен в .Net?

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

Итак, мы имеем String.IsNullOrEmpty(MyString)

и мы могли бы написать метод расширения, чтобы включить myString.IsNullOrEmpty(), хотя это, возможно, не самая большая идея. Смотрите: Расширяет класс String с запуском IsNullOrEmpty?.

Итак, мой вопрос: почему MS не пишет эту функциональность как часть .Net framework? Есть ли какая-то оценка эффективности? И в более общем плане, почему любой метод или свойство, которые считаются достаточно ценными для построения, доступные через объект String, не могут быть доступны как член любого объекта типа строки?

4b9b3361

Ответ 1

Статический метод String.IsNullOrEmpty был введен в .NET Framework версии 2.0. Методы расширения были внедрены в .NET Framework версии 3.5 вместе с LINQ. Поэтому у Microsoft не было этой опции при введении IsNullOrEmpty.

Конечно, IsNullOrEmpty не может быть методом экземпляра String, так как вы не можете вызвать метод для ссылки, которая null. Однако вы можете вызвать метод расширения для такой ссылки, поскольку синтаксис метода расширения - это просто синтаксический сахар для вызова статического метода.


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

string s = null;
bool result = s.IsNullOrEmpty();

В комментарии кто-то притворяется, что этот вызов вызовет NullReferenceException. Метод расширения будет объявлен следующим образом:

public static class StringExtensions
{
    public static bool IsNullOrEmpty(this string s)
    {
        return s == null || s.Length == 0;
    }
}

... и будет использоваться так...

 string s = null;
 bool result = s.IsNullOrEmpty();

... который является просто синтаксическим сахаром для...

 string s = null;
 bool result = StringExtensions.IsNullOrEmpty(s);

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

Ответ 2

Как правило, считается неправильной практикой, чтобы метод расширения не прерывался при вызове в null ссылке. Это связано с тем, что просто прочитав код, вы не можете сказать, что вызывается метод расширения. Ваша интуиция будет заключаться в том, чтобы вызвать вызов ((string)null).IsNullOrEmpty().

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

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

Авторы каркаса явно не согласились. Я также думаю, что этот метод не должен входить в .NET Framework, потому что он является своего рода "продвинутым" и препятствует обучаемости. Новичок может спросить: "Да? Иногда я могу безопасно ссылаться на нулевую ссылку, иногда я не могу? Как сказать, когда?".

Ответ 3

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

Шутки в стороне, так реализуется метод:

public static bool IsNullOrEmpty(string value)
{
  if (value != null)
    return value.Length == 0;
  else
    return true;
}

Ясно, что условие всегда будет истинным в случае строковых экземпляров.

Кроме того, одна маленькая деталь. Возьмем, например, string.Concat, который является статическим методом. Было бы разумным, например, удивляться, почему нет метода относительного экземпляра; взглянув на его реализацию, я считаю, что они хотели сделать эти методы максимально возможными. При передаче аргументов методу в случае нулевых ссылок они заменяются пустыми строками, а не имеют исключения. Это может быть полезно, когда вы не знаете заранее, если ваша строка (-ы) действительно будет содержать значение или будет равна null, и я предполагаю, что разработчики фреймворков решили, что было бы лучше внести вклад в чтение кода путем обработки нулевых строк как пустые и сохраняя конечный пользователь дополнительной проверкой. Разумеется, если string.Concat был методом экземпляра (или, по крайней мере, имел альтернативу), пользователь все равно мог передавать нулевые аргументы, но используемый экземпляр обязательно будет недействительным.