5 ответов:
решение
можно использовать
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; }это точно так же, как и оригинал образец.
объяснение
почему бы и нет
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как описано выше). Итак, опять же, не говоря о том, что сам необязательный параметр нуждается в постоянном, но известном компилятору значении.
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.)можно использовать на любой тип.
принятый ответ не работает 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(); } }
компилятор вполне корректен;
Guid.Emptyне является константой времени компиляции. Вы можете попробовать сделать перегрузку метода следующим образом:public void Problem() { Problem(Guid.Empty); }
Comments