¿Cómo puedo predeterminar un parámetro a Guid.Empty en C#?

Resuelto Ian Ringrose asked hace 13 años • 5 respuestas

Deseo decir:

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

Pero el compilador se queja de que Guid.Empty no es una constante de tiempo de compilación.

Como no deseo cambiar la API, no puedo usar:

 Nullable<Guid>
Ian Ringrose avatar Feb 25 '11 20:02 Ian Ringrose
Aceptado

Solución

Puedes usar new Guid()en su lugar

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

También puedes usardefault(Guid)

default(Guid)También funcionará exactamente como new Guid().

Debido a que Guid es un tipo de valor, no un tipo de referencia, default(Guid)no es igual a null, por ejemplo, sino que equivale a llamar al constructor predeterminado.

Lo que significa que esto:

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

Es exactamente igual que el ejemplo original.

Explicación

¿Por qué no Guid.Emptyfuncionó?

La razón por la que recibe el error es porque Emptyse define como:

public static readonly Guid Empty;

Entonces, es una variable, no una constante (definida como static readonlyno como const). El compilador solo puede tener valores conocidos por el compilador como valores predeterminados de los parámetros del método (no conocidos solo en tiempo de ejecución).

La causa principal es que no puedes tener un constof any struct, a diferencia enumde por ejemplo. Si lo intentas, no se compilará.

La razón, una vez más, es que structno es un tipo primitivo.
Para obtener una lista de todos los tipos primitivos en .NET, consulte http://msdn.microsoft.com/en-gb/library/system.typecode.aspx
(tenga en cuenta que enumgeneralmente hereda int, que es un primitivo)

¡ Pero new Guid()tampoco es una constante!

No digo que necesite una constante. Necesita algo que pueda decidirse en tiempo de compilación. Emptyes un campo, por lo que su valor no se conoce en tiempo de compilación (solo al comienzo del tiempo de ejecución).

El valor del parámetro predeterminado debe conocerse en el momento de la compilación, que puede ser un constvalor o algo definido usando una característica de C# que hace que el valor se conozca en el momento de la compilación, como default(Guid)o new Guid()(que se decide en el momento de la compilación para structs ya que no se puede modificar el structconstructor en código).

Si bien puede proporcionar defaulto newfácilmente, no puede proporcionar un const(porque no es un tipo primitivo o enumcomo se explicó anteriormente). Entonces, nuevamente, no digo que el parámetro opcional en sí necesite una constante, pero un valor conocido por el compilador.

Meligy avatar Feb 25 '2011 13:02 Meligy

Guid.Emptyes equivalente a new Guid(), que es equivalente a default(Guid). Entonces puedes usar:

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

o

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

Tenga en cuenta que el new Foo()valor sólo es aplicable cuando:

  • Realmente estás llamando al constructor sin parámetros.
  • Fooes un tipo de valor

En otras palabras, cuando el compilador sabe que en realidad es solo el valor predeterminado para el tipo :)

(Curiosamente, estoy 99,9% seguro de que no llamará a ningún new Foo()constructor personalizado que haya creado. No puede crear dicho constructor en un tipo de valor en C#, pero puede hacerlo en IL).

Puede utilizar la default(Foo)opción para cualquier tipo.

Jon Skeet avatar Feb 25 '2011 13:02 Jon Skeet

¿No puedes usar:

default ( Guid ) ?

Nick avatar Feb 25 '2011 13:02 Nick

La respuesta aceptada no funciona en ASP.NET MVC y provoca este error de tiempo de ejecución:

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

En su lugar, puede hacer lo siguiente:

public void Problem(Guid? optional)
{
    if (optional == null)
    {
        optional = new Guid();
    }
}
Majix avatar May 13 '2014 20:05 Majix