2009-06-04 18 views
7

Por qué es que el siguiente código no funcionará:matemáticas con enumeraciones (por ejemplo DAYOFWEEK) en C#

endDate.AddDays(7-endDate.DayOfWeek); 

Si bien esto:

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

?

(Por "no funcionará" Me refiero a los resultados en el siguiente error de compilación: "no se puede convertir de 'System.DayOfWeek' a 'doble'")

+2

Por alguna interesante análisis de los errores de compilación relacionados con esta función, consulte: http://blogs.gotdotnet.com/ericlippert/archive/2006/03/28/the-root-of-all-evil -parte uno.aspx y http://blogs.gotdotnet.com/ericlippert/archive/2006/03/29/the-root-of-all-evil-part-two.aspx –

+1

Para cualquiera que esté buscando las publicaciones del blog de Eric , se han movido a http://blogs.msdn.com/b/ericlippert/archive/2006/03/28/the-root-of-all-evil-part-one.aspx y http: // blogs. msdn.com/b/ericlippert/archive/2006/03/29/the-root-of-all-evil-part-two.aspx –

Respuesta

12

Para ampliar lo dicho Lasse (o más bien, hacerlo un poco más explícito).

porque 0 es convertible a un tipo de enumeración,

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

Y ya que se puede restar una enumeración de otro y obtener una diferencia de número entero:

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

Por lo tanto, dado que el resultado de la resta es un int, puede agregar 7 a él.

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

Por lo tanto, si el valor de enumeración del lunes es 1

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

Sin embargo, no se puede hacer a la inversa.

endDate.DayOfWeek - 0 + 7, 

porque el tipo de resultado del cálculo depende del lado izquierdo. Por lo tanto, mientras que 0 - endDate.DayOfWeek da como resultado un entero, endDate.DayOfWeek - 0 da como resultado una enumeración DayOfWeek.

Lo más interesante es que podría usar este efecto secundario para obtener el valor de una enumeración sin fundición, aunque consideraría que esto es harto y confuso ... así debe evitarse.

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

Esto es muy interesante. La forma correcta de hacerlo es:

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

embargo, su pregunta no se trata de una solución, sino una razón para el comportamiento. Tiene algo que ver con la forma en que el compilador trata a cero. Cualquiera de las líneas falla si no hay cero presente, mientras que ambas líneas funcionan si hay un cero presente.

+0

Además endDate.AddDays (DayOfWeek.Sunday - e.DayOfWeek) funciona. Está convirtiendo cero en el campo dominical de DayOfWeek. Ahora, lo que es realmente extraño es que el "truco cero" falla para la suma. Meaning endDate.AddDays (DayOfWeek.Sunday + e.DayOfWeek) no se compilará. –

4

Puede restar dos valores de enumeración para obtener su diferencia de valor entero:

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(); 
     } 
    } 
} 

imprimirá 3.

pero no se puede añadir, probablemente no tiene sentido.

En el caso de "0", 0 es auto-convertible a todos los tipos enum, por lo que básicamente "0 - enumvalue" significa lo mismo que "(enumtype) 0 - enumvalue", que nuevamente funciona.