133 votes

C# 4.0: puis-je utiliser un laps de Temps comme une option de paramètre avec une valeur par défaut?

Ces deux générer une erreur en disant qu'il faut être une constante de compilation:

void Foo(TimeSpan span = TimeSpan.FromSeconds(2.0))
void Foo(TimeSpan span = new TimeSpan(2000))

Tout d'abord, quelqu'un peut m'expliquer pourquoi ces valeurs ne peuvent pas être déterminés au moment de la compilation? Et est-il un moyen de spécifier une valeur par défaut pour l'option d'un objet TimeSpan?

183voto

Josh Points 38617

Vous pouvez travailler autour de cette très facilement en changeant votre signature.

void Foo(TimeSpan? span = null) {

   if (span == null) { span = TimeSpan.FromSeconds(2); }

   ...

}

Je doit préciser la raison de ces expressions dans votre exemple ne sont pas des constantes de compilation est parce que au moment de la compilation, le compilateur ne peut pas simplement exécuter laps de Temps.FromSeconds(2.0) et coller les octets de la suite dans votre code compilé.

Considérez, par exemple, si vous avez essayé d'utiliser DateTime.Maintenant à la place. La valeur de type DateTime.Aujourd'hui les changements à chaque fois qu'il est exécuté. Ou supposons que TimeSpan.FromSeconds a pris en compte la gravité. C'est absurde, mais aussi les règles de la compilation des constantes de temps de ne pas faire de cas particuliers juste parce que nous savons que TimeSpan.FromSeconds est déterministe.

32voto

phoog Points 22667

Mon VB6 patrimoine me rend mal à l'aise avec l'idée de considérer les "valeur nulle" et "valeur manquante" d'être équivalent. Dans la plupart des cas, il est probablement très bien, mais vous pourriez avoir un effet secondaire involontaire, ou vous pourriez avaler un état exceptionnel (par exemple, si la source d' span est une propriété ou d'une variable qui ne doit pas être nul, mais est).

Je tiens donc à la surcharge de la méthode:

void Foo()
{
    Foo(TimeSpan.FromSeconds(2.0));
}
void Foo(TimeSpan span)
{
    //...
}

26voto

Cela fonctionne très bien:

void Foo(TimeSpan span = default(TimeSpan))

16voto

JaredPar Points 333733

L'ensemble de valeurs qui peut être utilisé comme valeur par défaut sont les mêmes que peut être utilisé pour un attribut argument. La raison étant que les valeurs par défaut sont codées dans les métadonnées à l'intérieur de l' DefaultParameterValueAttribute.

Pourquoi il ne peut pas être déterminé au moment de la compilation. L'ensemble des valeurs et des expressions sur ces valeurs autorisées au moment de la compilation est répertorié dans la section 7.18 C# lang spec. En termes de valeurs autorisée est limitée à

  • Les littéraux dont la valeur null
  • Des références à d'autres valeurs const
  • Les valeurs d'énumération
  • La valeur par défaut de l'expression

Le type TimeSpan ne rentre dans aucune de ces listes et ne peut donc pas être utilisé comme une constante.

12voto

nawfal Points 13500
void Foo(TimeSpan span = default(TimeSpan))
{
    if (span == default(TimeSpan)) 
        span = TimeSpan.FromSeconds(2); 
}

fournis default(TimeSpan) n'est pas une valeur valide pour la fonction.

Ou

//this works only for value types which TimeSpan is
void Foo(TimeSpan span = new TimeSpan())
{
    if (span == new TimeSpan()) 
        span = TimeSpan.FromSeconds(2); 
}

fournis new TimeSpan() n'est pas une valeur valide.

Ou

void Foo(TimeSpan? span = null)
{
    if (span == null) 
        span = TimeSpan.FromSeconds(2); 
}

Cela devrait être mieux vu chances d' null de la valeur étant une valeur valide pour la fonction sont rares.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X