Je souhaite dire:
public void Problem(Guid optional = Guid.Empty)
{
}
Mais le compilateur se plaint que Guid.Empty n'est pas une constante de temps de compilation.
Comme je ne souhaite pas changer l'API, je ne peux pas utiliser:
Nullable<Guid>
c#
c#-4.0
optional-parameters
Ian Ringrose
la source
la source
Nullable<Guid> optional = null
(ou plus brièvementGuid? optional = null
)? Tous les Guids qui lui sont actuellement transmis seront forcés sans qu'aucune modification de code ne soit nécessaire.Réponses:
Solution
Vous pouvez utiliser à la
new Guid()
placeVous pouvez aussi utiliser
default(Guid)
default(Guid)
fonctionnera également exactement commenew Guid()
.Étant donné que Guid est un type valeur et non un type référence, il
default(Guid)
n'est donc pas égal à,null
par exemple, il est égal à l'appel du constructeur par défaut.Ce qui signifie que ceci:
C'est exactement le même que l'exemple original.
Explication
Pourquoi n'a pas
Guid.Empty
fonctionné?La raison pour laquelle vous obtenez l'erreur est qu'elle
Empty
est définie comme:Donc, c'est une variable, pas une constante (définie comme
static readonly
non commeconst
). Le compilateur ne peut avoir que des valeurs connues du compilateur comme valeurs par défaut des paramètres de méthode (non connues uniquement à l'exécution).La cause racine est que vous ne pouvez pas avoir
const
de toutstruct
, à la différenceenum
par exemple. Si vous essayez, il ne se compilera pas.La raison est encore une fois que ce
struct
n'est pas un type primitif.Pour une liste de tous les types primitifs dans .NET, voir http://msdn.microsoft.com/en-gb/library/system.typecode.aspx
(notez que
enum
généralement hériteint
, qui est une primitive)Mais ce
new Guid()
n'est pas non plus une constante!Je ne dis pas qu'il faut une constante. Il a besoin de quelque chose qui peut être décidé au moment de la compilation.
Empty
est un champ, donc sa valeur n'est pas connue au moment de la compilation (seulement au tout début de l'exécution).La valeur du paramètre par défaut doit être connue au moment de la compilation, qui peut être une
const
valeur, ou quelque chose de défini à l'aide d'une fonctionnalité C # qui rend la valeur connue au moment de la compilation, commedefault(Guid)
ounew Guid()
(qui est décidé au moment de la compilation pourstruct
s car vous ne pouvez pas modifier lestruct
constructeur dans code).Bien que vous puissiez fournir
default
ounew
facilement, vous ne pouvez pas fournir unconst
(car ce n'est pas un type primitif ou unenum
comme expliqué ci-dessus). Donc, encore une fois, ne pas dire que le paramètre facultatif lui-même a besoin d'une constante, mais une valeur connue du compilateur.la source
new Guid()
n'est pas une expression constante, par exemple. La spécification C # définit assez clairement ce qui est autorisé, y compris, mais sans s'y limiter, les constantes. (Juste pour être clair, il s'agit en fait d' une constante de temps de compilation, mais pas d'une "expression constante" en termes de spécification C #).default
nos jours :)Guid.Empty
est équivalent ànew Guid()
, qui est équivalent àdefault(Guid)
. Vous pouvez donc utiliser:ou
Notez que la
new Foo()
valeur est uniquement applicable lorsque:Foo
est un type valeurEn d'autres termes, lorsque le compilateur sait qu'il s'agit en réalité de la valeur par défaut du type :)
( Fait intéressant, je suis 99,9% sûr que ce ne sera pas appeler de coutume
new Foo()
constructeur que vous avez créé. Vous ne pouvez pas créer un tel constructeur dans un type de valeur en C #, mais vous pouvez le faire en IL.)Vous pouvez utiliser l'
default(Foo)
option pour n'importe quel type.la source
Nullable<Guid>
, potentiellement.Ne pouvez-vous pas utiliser:
default ( Guid )
?la source
Operator '??' cannot be applied to operands of type 'System.Guid' and 'System.Guid'
La réponse acceptée ne fonctionne pas dans ASP.NET MVC et provoque cette erreur d'exécution:
Au lieu de cela, vous pouvez effectuer les opérations suivantes:
la source
Le compilateur est tout à fait correct;
Guid.Empty
n'est pas une constante de compilation. Vous pouvez essayer de créer une surcharge de méthode comme celle-ci:la source
Guid x = default(Guid)
la solution, rappelez-vous que l'ajout d'une autre surcharge de fonction ne complique pas plus l'API que l'ajout d'un argument facultatif. C'est vraiment ce que fait un argument optionnel de toute façon.