2009-06-04 5 views
7

Pourquoi est-ce que le code suivant ne fonctionnera pas:Math avec énumérations (par exemple DayOfWeek) en C#

endDate.AddDays(7-endDate.DayOfWeek); 

Bien que cela:

endDate.AddDays(0-endDate.DayOfWeek + 7); 

?

(par « ne fonctionne pas », je veux dire des résultats dans l'erreur de compilation suivante: « ne peut pas convertir « System.DayOfWeek » à« double »)

+2

Pour une analyse intéressante de bugs du compilateur impliquant cette fonctionnalité, consultez: http://blogs.gotdotnet.com/ericlippert/archive/2006/03/28/the-root-of-all-evil -partie un.aspx et http://blogs.gotdotnet.com/ericlippert/archive/2006/03/29/the-root-of-all-evil-part-two.aspx –

+1

Pour tous ceux qui recherchent les articles du blog d'Eric , ils sont passés à http://blogs.msdn.com/b/ericlippert/archive/2006/03/28/the-root-of-all-evil-part-one.aspx et http: // blogs. msdn.com/b/ericlippert/archive/2006/03/29/the-root-of-all-evil-part-two.aspx –

Répondre

12

Pour développer ce que dit Lasse (ou plutôt, le rendre un peu plus explicite).

Parce que 0 est convertable à un type Enum,

0 - endDate.DayOfWeek becomes 
(DayOfWeek)0 - endDate.DayOfWeek 

Et puisque vous pouvez soustraire un ENUM d'un autre et obtenir une différence de nombre entier:

(DayOfWeek)0 - endDate.DayOfWeek == (int)endDate.DayOfWeek 

Ainsi, étant donné que le résultat de la soustraction est un int, vous pouvez alors y ajouter 7.

endDate.AddDays(0-endDate.DayOfWeek + 7); 

Ainsi, si la valeur Enum lundi est 1

0 - endDate.DayOfWeek == -1 + 7 == 6 

Cependant, vous ne pouvez pas faire l'inverse.

endDate.DayOfWeek - 0 + 7, 

car le type de résultat du calcul dépend du côté le plus à gauche. Ainsi, alors que 0 - endDate.DayOfWeek aboutit à un entier, endDate.DayOfWeek - 0 aboutit à un enum DayOfWeek.

Plus intéressant, vous pouvez utiliser cet effet de bord pour obtenir la valeur d'une énumération sans lancer, bien que je considérerais ce hackish et confus ... donc à éviter.

int enumValue = -(0 - endDate.DayOfWeek); 
4

Ceci est très intéressant. La bonne façon de le faire est:

endDate.AddDays(7 - (int)endDate.DayOfWeek); 

Mais, votre question ne concerne pas une solution, mais une raison pour le comportement. Cela a quelque chose à voir avec la façon dont le compilateur traite un zéro. L'une ou l'autre ligne échoue si aucun zéro n'est présent, alors que les deux lignes fonctionnent si un zéro est présent.

+0

De plus, endDate.AddDays (DayOfWeek.Sunday - e.DayOfWeek) fonctionne. Il convertit zéro dans le champ Sunday de DayOfWeek. Maintenant, ce qui est vraiment étrange, c'est que le "truc nul" échoue pour l'addition. Signification endDate.AddDays (DayOfWeek.Sunday + e.DayOfWeek) ne compilera pas. –

4

Vous pouvez soustraire deux valeurs ENUM pour obtenir leur différence de valeur entière:

using System; 

namespace ConsoleApplication10 
{ 
    public enum X { A, B, C, D } 
    public class Program 
    { 
     static void Main() 
     { 
      var x = X.D + X.A; 
      Console.Out.WriteLine(x); 
      Console.In.ReadLine(); 
     } 
    } 
} 

imprimera 3.

Mais vous ne pouvez pas ajouter, fait probablement aucun sens.

Dans le cas de "0", 0 est auto-convertible en tous les types d'énumération, donc "0 - énumvalue" signifie la même chose que "(enumtype) 0 - enumvalue", qui fonctionne à nouveau.

Questions connexes