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,nullpor 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.Emptyfuncionó?La razón por la que obtiene el error es porque
Emptyse define como:Entonces, es una variable, no una constante (definida como
static readonlyno 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
constningunastruct, a diferencia de,enumpor ejemplo. Si lo prueba, 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 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.
Emptyes 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
constvalor 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 parastructs ya que no puede modificar elstructconstructor en código).Si bien puede proporcionar
defaulto nonew, no puede proporcionar unconst(porque no es un tipo primitivo oenumcomo 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 #).defaulthoy en día :)Guid.Emptyes equivalente anew Guid(), que es equivalente adefault(Guid). Entonces puedes usar:o
Tenga en cuenta que el
new Foo()valor solo es aplicable cuando:Fooes 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.EmptyNo 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.