Как я могу по умолчанию параметр Guid.Empty в C #? - PullRequest
166 голосов
/ 25 февраля 2011

Я хочу сказать:

public void Problem(Guid optional = Guid.Empty)
{
}

Но компилятор жалуется, что Guid.Empty не является постоянной времени компиляции.

Поскольку я не хочу менять API, я не могу использовать:

 Nullable<Guid>

Ответы [ 5 ]

207 голосов
/ 25 февраля 2011

Решение

Вы можете использовать new Guid() вместо

public void Problem(Guid optional = new Guid())
{
  // when called without parameters this will be true
  var guidIsEmpty = optional == Guid.Empty;
}

Вы также можете использовать default(Guid)

default(Guid) также будет работать точно так же, как new Guid().

Поскольку Guid является типом значения, а не ссылочным типом, поэтому default(Guid) не равен, например, null, вместо этого он равен вызову конструктора по умолчанию.

Что означает, что это:

public void Problem(Guid optional = default(Guid))
{
  // when called without parameters this will be true
  var guidIsEmpty = optional == Guid.Empty;
}

Это точно так же, как оригинальный пример.

Объяснение * * 1023 Почему Guid.Empty не работает? Причина, по которой вы получаете ошибку, заключается в том, что Empty определяется как: public static readonly Guid Empty; Итак, это переменная, а не константа (определяется как static readonly, а не const). Компилятор может иметь только значения, известные компилятору, в качестве значений параметров метода по умолчанию (не известно только во время выполнения). Основная причина в том, что вы не можете иметь const любого struct, в отличие от enum, например. Если вы попробуете это, он не скомпилируется. Причина еще раз в том, что struct не является примитивным типом.
Список всех примитивных типов в .NET см. http://msdn.microsoft.com/en-gb/library/system.typecode.aspx
(обратите внимание, что enum обычно наследует int, что является примитивом) Но new Guid() тоже не константа! Я не говорю, что нужна константа. Нужно что-то, что можно решить во время компиляции. Empty - это поле, поэтому его значение неизвестно во время компиляции (только в самом начале времени выполнения). Значение параметра по умолчанию должно быть известно во время компиляции, которое может быть значением const или определенным с помощью функции C #, которая делает значение известным во время компиляции, например, default(Guid) или new Guid() (который определяется во время компиляции в течение struct с, поскольку вы не можете изменить конструктор struct в коде). Хотя вы можете легко предоставить default или new, вы не можете предоставить const (потому что это не примитивный тип или enum, как объяснено выше). Итак, опять же, не говоря о том, что самому необязательному параметру нужна постоянная, но известная компилятору величина.

148 голосов
/ 25 февраля 2011

Guid.Empty эквивалентно new Guid(), что эквивалентно default(Guid).Таким образом, вы можете использовать:

public void Problem(Guid optional = default(Guid))

или

public void Problem(Guid optional = new Guid())

Обратите внимание, что значение new Foo() только применимо, когда:

  • Вы действительно вызываете конструктор без параметров
  • Foo - это тип значения

Другими словами, когда компилятор знает, что это действительно просто значение по умолчаниюзначение для типа:)

(Интересно, что я на 99,9% уверен, что не вызовет любой пользовательский конструктор new Foo(), который вы могли создать. Вы не можете создать такойконструктор в типе значения в C #, но вы можете сделать это в IL.)

Вы можете использовать опцию default(Foo) для любого типа.

17 голосов
/ 25 февраля 2011

Не можете ли вы использовать:

default ( Guid )?

7 голосов
/ 14 мая 2014

Принятый ответ не работает в ASP.NET MVC и вызывает эту ошибку времени выполнения:

[ArgumentException: The parameters dictionary contains a null entry for parameter 'optional' of non-nullable type 'System.Guid' for method 'System.Web.Mvc.ActionResult Problem(System.Guid)' ....

Вместо этого вы можете сделать следующее:

public void Problem(Guid? optional)
{
    if (optional == null)
    {
        optional = new Guid();
    }
}
4 голосов
/ 25 февраля 2011

Компилятор вполне корректен; Guid.Empty не является константой времени компиляции. Вы можете попробовать перегрузить метод следующим образом:

public void Problem()
{
    Problem(Guid.Empty);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...