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 modifier l’API, je ne peux pas utiliser:
Nullable<Guid>
new Guid()
à la placepublic void Problem(Guid optional = new Guid())
{
// when called without parameters this will be true
var guidIsEmpty = optional == Guid.Empty;
}
default(Guid)
default(Guid)
fonctionnera également exactement comme new Guid()
.
Comme Guid est un type de valeur et non de type référence, default(Guid)
n'est pas égal à null
par exemple, il équivaut à appeler le constructeur par défaut.
Ce qui signifie que ceci:
public void Problem(Guid optional = default(Guid))
{
// when called without parameters this will be true
var guidIsEmpty = optional == Guid.Empty;
}
C'est exactement la même chose que l'exemple original.
Guid.Empty
N'a-t-il pas fonctionné?La raison pour laquelle vous obtenez l'erreur est parce que Empty
est défini comme suit:
public static readonly Guid Empty;
Il s’agit donc d’une variable et non d’une constante (définie comme static readonly
Et non de const
). Le compilateur ne peut avoir que des valeurs connues du compilateur en tant que valeurs par défaut des paramètres de méthode (non connues à l'exécution).
La cause fondamentale est que vous ne pouvez pas avoir un const
de n'importe quel struct
, contrairement à enum
par exemple. Si vous l'essayez, il ne sera pas compilé.
La raison encore une fois est que struct
n'est pas un type primitif.
Pour obtenir la liste de tous les types primitifs dans .NET, voir http://msdn.Microsoft.com/en-gb/library/system.typecode.aspx
(notez que enum
hérite généralement de int
, qui est une primitive)
new Guid()
n'est pas une constante aussi!Je ne dis pas qu'il a besoin d'une constante. Il faut quelque chose qui puisse être décidé en temps de compilation. Empty
est un champ, sa valeur n'est donc pas connue au moment de la compilation (uniquement au tout début de son exécution).
La valeur du paramètre par défaut doit être connue au moment de la compilation, ce qui peut être une valeur const
, ou un élément défini à l'aide d'une fonctionnalité C # qui permet de connaître la valeur au moment de la compilation, comme default(Guid)
ou new Guid()
(décidé lors de la compilation pour struct
s car vous ne pouvez pas modifier le constructeur struct
dans le code).
Bien que vous puissiez fournir default
ou new
facilement, vous ne pouvez pas fournir un const
(car ce n'est pas un type primitif ou un enum
comme expliqué ci-dessus). Donc, encore une fois, ne pas dire que le paramètre optionnel lui-même a besoin d’une constante, mais d’une valeur connue du compilateur.
Guid.Empty
Équivaut à new Guid()
, ce qui équivaut à default(Guid)
. Pour que vous puissiez utiliser:
public void Problem(Guid optional = default(Guid))
ou
public void Problem(Guid optional = new Guid())
Notez que la valeur new Foo()
est niquement applicable lorsque:
Foo
est un type de valeurEn d'autres termes, quand le compilateur sait que c'est vraiment la valeur par défaut pour le type :)
(Fait intéressant, je suis sûr à 99,9% que cela ne sera pas appeler n'importe quel constructeur personnalisé new Foo()
que vous auriez 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'option default(Foo)
pour le type any.
Ne pouvez-vous pas utiliser:
default ( Guid )
?
La réponse acceptée ne fonctionne pas dans ASP.NET MVC et provoque cette erreur d'exécution:
[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)' ....
Au lieu de cela, vous pouvez effectuer les opérations suivantes:
public void Problem(Guid? optional)
{
if (optional == null)
{
optional = new Guid();
}
}
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 ceci:
public void Problem()
{
Problem(Guid.Empty);
}