views:

3212

answers:

4

Why is it that the following code won't work:

endDate.AddDays(7-endDate.DayOfWeek);

While this will:

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

?

(By "won't work" I mean results in the following compilation error: "cannot convert from 'System.DayOfWeek' to 'double'")

+3  A: 

This is very interesting. The right way to do this is:

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

But, your question isn't about a solution, but a reason for the behavior. It has something to do with the way the compiler treats a zero. Either line fails if no zero is present, while both lines work if a zero is present.

John Fisher
Additionally endDate.AddDays(DayOfWeek.Sunday - e.DayOfWeek) does work. It's converting zero into the Sunday field of DayOfWeek. Now what's really odd is the "zero trick" fails for addition. Meaning endDate.AddDays(DayOfWeek.Sunday + e.DayOfWeek) will not compile.
Colin Burnett
+2  A: 

You can subtract two enum values to get their integer value difference:

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

Will print out 3.

But you can't add, probably makes no sense.

In the case of "0", 0 is auto-convertible to all enum types, so basically "0 - enumvalue" means the same as "(enumtype)0 - enumvalue", which again works.

Lasse V. Karlsen
+6  A: 

To expand upon what Lasse said (or rather, make it a little more explicit).

Because 0 is convertable to an Enum type,

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

And since you can subtract one enum from another and get an integer difference:

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

Thus, since the result of the subtraction is an int, you can then add 7 to it.

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

So, if Monday's Enum value is 1

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

However, you can't do the reverse.

endDate.DayOfWeek - 0 + 7,

because the result type of the calculation is dependant upon the leftmost side. Thus, while 0 - endDate.DayOfWeek results in an integer, endDate.DayOfWeek - 0 results in an enum DayOfWeek.

Most interestingly, you could use this side-effect to get the value of an enum without casting, though I would consider this hackish and confusing... thus to be avoided.

int enumValue = -(0 - endDate.DayOfWeek);
Mystere Man
A: 

Great explanation thanks. I'm new to C# and dotnet and I was having trouble getting my head around this.

Tony Springford