Как я могу по умолчанию параметр Guid.Пусто в C#?



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



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


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



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



 Nullable<Guid>
1322   5  

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.)

можно использовать на любой тип.

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

default ( Guid ) ?

принятый ответ не работает 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

    Ничего не найдено.