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>
c#
c#-4.0
optional-parameters
Ian Ringrose
fuente
fuente
Nullable<Guid> optional = null
(o más brevementeGuid? optional = null
)? Cualquier guía que se le pase actualmente coaccionará sin ningún cambio de código necesario.Respuestas:
Solución
Puedes usar
new Guid()
en su lugarTambién puedes usar
default(Guid)
default(Guid)
También funcionará exactamente comonew Guid()
.Debido a que Guid es un tipo de valor, no un tipo de referencia, por lo tanto,
default(Guid)
no es igual a,null
por ejemplo, es igual a llamar al constructor predeterminado.Lo que significa que esto:
Es exactamente lo mismo que el ejemplo original.
Explicación
¿Por qué no
Guid.Empty
funcionó?La razón por la que obtiene el error es porque
Empty
se define como:Entonces, es una variable, no una constante (definida como
static readonly
no comoconst
). El compilador solo puede tener valores conocidos del compilador como valores predeterminados de los parámetros del método (no conocidos solo en tiempo de ejecución).La causa raíz es que no puedes tener un
const
ningunastruct
, a diferencia de,enum
por ejemplo. Si lo prueba, no se compilará.La razón una vez más es que
struct
no 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
enum
generalmente heredaint
, que es un primitivo)Pero
new Guid()
tampoco es una constante!No digo que necesite una constante. Necesita algo que se pueda decidir en tiempo de compilación.
Empty
es un campo, por lo tanto, su valor no se conoce en tiempo de compilación (solo al comienzo del tiempo de ejecución).El valor predeterminado del parámetro debe conocerse en tiempo de compilación, que puede ser un
const
valor o algo definido mediante una función de C # que hace que el valor sea conocido en tiempo de compilación, comodefault(Guid)
onew Guid()
(que se decide en tiempo de compilación parastruct
s ya que no puede modificar elstruct
constructor en código).Si bien puede proporcionar
default
o nonew
, no puede proporcionar unconst
(porque no es un tipo primitivo oenum
como se explicó anteriormente). Entonces, nuevamente, no digo que el parámetro opcional en sí mismo necesite un valor conocido constante, pero compilador.fuente
new Guid()
no es una expresión constante, por ejemplo. La especificación de C # define claramente lo que está permitido, incluidas , entre otras, las constantes. (Solo para ser claros, efectivamente es una constante de tiempo de compilación, solo que no es una "expresión constante" en términos específicos de C #).default
hoy en día :)Guid.Empty
es equivalente anew Guid()
, que es equivalente adefault(Guid)
. Entonces puedes usar:o
Tenga en cuenta que el
new Foo()
valor solo es aplicable cuando:Foo
es un tipo de valorEn otras palabras, cuando el compilador sabe que realmente 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 usar la
default(Foo)
opción para cualquier tipo.fuente
Nullable<Guid>
, potencialmente.¿No puedes usar:
default ( Guid )
?fuente
Operator '??' cannot be applied to operands of type 'System.Guid' and 'System.Guid'
La respuesta aceptada no funciona en ASP.NET MVC y causa este error de tiempo de ejecución:
En su lugar, puede hacer lo siguiente:
fuente
El compilador es bastante correcto;
Guid.Empty
No es una constante de tiempo de compilación. Puede intentar hacer una sobrecarga de método como este:fuente
Guid x = default(Guid)
la solución, recuerde que agregar otra sobrecarga de funciones no complica más la API que agregar un argumento opcional. Eso es realmente lo que hace un argumento opcional de todos modos.