Нельзя использовать строку.Пустое значение по умолчанию для необязательного параметра


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

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

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

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

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

обновление
Просто последующий комментарий. Согласно MSDN:

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

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

9 78

9 ответов:

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

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

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

const string String_Empty = "";

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

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

из исходного вопроса:

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

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

из сообщения о щедрости контртеррористического террориста:

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

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

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

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

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

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

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

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

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

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

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

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

public static readonly string Empty

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

Если вам действительно не нравятся строковые литералы, вы можете использовать:

public static string MyFunction(string myParam= default(string))

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

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

например:

if(someString == string.Empty)
{

}

vs

if(someString == "")
{

}

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

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

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