Невозможно использовать String.Empty в качестве значения по умолчанию для необязательного параметра. - PullRequest
85 голосов
/ 23 апреля 2010

Я читаю Эффективный C # Биллом Вагнером. В Элемент 14 - Минимизировать повторяющуюся логику инициализации он показывает следующий пример использования новой функции дополнительных параметров в конструкторе:

public MyClass(int initialCount = 0, string name = "")

Обратите внимание, что он использовал "" вместо string.Empty.
Он комментирует:

Вы заметите [в примере выше], что второй конструктор указал "" для значения по умолчанию в параметре name , а не в более привычном string.Empty. Это потому, что string.Empty не является константой времени компиляции. Это статическое свойство, определенное в строковом классе. Поскольку это не константа компиляции, вы не можете использовать ее в качестве значения по умолчанию для параметра.

Если мы не можем использовать статический string.Empty во всех ситуациях, разве это не противоречит его цели? Я думал, что мы будем использовать его, чтобы быть уверенным, что у нас есть независимые от системы средства ссылки на пустую строку. Мое понимание неверно? Спасибо.

UPDATE
Просто последующий комментарий. По данным MSDN:

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

Тогда мы также не сможем использовать System.Environment.NewLine или использовать новые экземпляры объектов в качестве значений по умолчанию. Я еще не использовал VS2010, и это разочаровывает!

Ответы [ 8 ]

59 голосов
/ 23 апреля 2010

Что касается компилятора C # 2.0, то в любом случае очень мало смысла в String.Empty, и на самом деле во многих случаях это пессимизация, поскольку компилятор может вставить некоторые ссылки на "", но не может сделать то же самое String.Empty.

В C # 1.1 было полезно избегать создания множества независимых объектов, содержащих пустую строку, но эти дни прошли. "" работает просто отлично.

52 голосов
/ 25 февраля 2012

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

const string String_Empty = "";

public static void PrintString(string s = String_Empty)
{
    Console.WriteLine(s);
}

[Кроме того, одна из причин предпочитать String.Empty над "" в целом, которая не упоминалась в других ответах, заключается в том, что существуют различные символы Юникода (столяры нулевой ширины и т. Д.) эффективно невидимы невооруженным глазом. То есть что-то вроде "" не обязательно является пустой строкой, тогда как с String.Empty вы точно знаете, что используете. Я понимаю, что это не распространенный источник ошибок, но это возможно.]

24 голосов
/ 03 марта 2012

Из оригинального вопроса:

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

Каким образом пустая строка может варьироваться от системы к системе? Это всегда строка без символов! Я был бы действительно напуган, если бы когда-нибудь нашел реализацию, где string.Empty == "" вернул false :) Это не то же самое, что и Environment.NewLine.

Из сообщения о борьбе с терроризмом:

Я хочу, чтобы String.Empty мог использоваться в качестве параметра по умолчанию в следующем выпуске C #. : D

Ну, это, конечно, не произойдет.

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

С string.Empty это действительно бессмысленно - использование "" будет делать то, что вы хотите; что больно использовать строковый литерал? (Я везде использую литерал - я никогда не использую string.Empty - но это другой аргумент.)

Вот что меня удивляет в этом вопросе - жалоба вращается вокруг чего-то, что не на самом деле вызывает реальную проблему. Это более важно в тех случаях, когда вы хотите, чтобы значение по умолчанию вычислялось во время выполнения, потому что оно может фактически отличаться Например, я мог бы представить случаи, когда вы хотите иметь возможность вызывать метод с параметром DateTime и иметь по умолчанию значение «текущее время». На данный момент единственный смутно элегантный обходной путь, который я знаю для этого:

public void RecordTime(string message, DateTime? dateTime = null)
{
    var realDateTime = dateTime ?? DateTime.UtcNow;
}

... но это не всегда уместно.

В заключение:

  • Я очень сомневаюсь, что это когда-нибудь станет частью C #
  • Для string.Empty это все равно бессмысленно
  • Для других значений, которые действительно не всегда имеют одно и то же значение, на самом деле может быть болью
7 голосов
/ 23 апреля 2010

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

4 голосов
/ 23 апреля 2010

Я думаю, что идея, стоящая за строкой, пуста: она улучшает читабельность. Это не похоже на символ новой строки, где есть разница между тем, как он представлен на разных платформах. Стыдно, его нельзя использовать в параметре по умолчанию. Тем не менее, это не вызовет никаких проблем, если вы портируете между Windows и чем-то вроде Mono в Linux.

3 голосов
/ 27 февраля 2012

Как к сведению, похоже, что к значениям, передаваемым конструкторам атрибутов, наложено такое же ограничение - они должны быть постоянными. Поскольку string.empty определяется как:

public static readonly string Empty

, а не фактическая константа, она не может быть использована.

1 голос
/ 22 июня 2015

Я использую string.Empty исключительно для удобства чтения.

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

Например:

if(someString == string.Empty)
{

}

против

if(someString == "")
{

}

Первое утверждение if кажется мне гораздо более продуманным и читабельным. Поскольку это всего лишь предпочтение, я действительно не вижу, как разбить поезд нужно использовать "" вместо string.Empty.

0 голосов
/ 26 сентября 2013

Возможно, лучшим решением этой проблемы является перегрузка этого метода, таким образом:

public static void PrintString() 
{ 
    PrintString(string.Empty);
}
...