Why do I have to cast enums to int in C#?

2020-08-26 03:47发布

This is my code:

internal enum WindowsMessagesFlags {
    WM_EXITSIZEMOVE      = 0x00000232,
    WM_DISPLAYCHANGE     = 0x0000007e,
    WM_MOVING            = 0x00000216,
}

protected override void WndProc(ref Message m) {
    switch(m.Msg) {
        case (int)WindowsMessagesFlags.WM_DISPLAYCHANGE:
            FixWindowSnapping();
            break;
        case (int)WindowsMessagesFlags.WM_EXITSIZEMOVE:
            SaveWindowProperties();
            break;
        case (int)WindowsMessagesFlags.WM_MOVING:
            KeepProperLocation(ref m);
            break;
    }
}

Is there anyway to prevent the casting?

3条回答
ら.Afraid
2楼-- · 2020-08-26 04:04

Sort of - cast m.Msg instead:

protected override void WndProc(ref Message m) {
    switch((WindowsMessagesFlags) m.Msg) {
        case WindowsMessagesFlags.WM_DISPLAYCHANGE:
                FixWindowSnapping();
                break;
        case WindowsMessagesFlags.WM_EXITSIZEMOVE:
                SaveWindowProperties();
                break;
        case WindowsMessagesFlags.WM_MOVING:
                KeepProperLocation(ref m);
                break;
    }
}

The reason you need the cast at all is because in C# enums aren't just numbers - they're numbers associated with the type. This prevents you from doing (without casting):

HttpStatusCode status = someWindowsMessageFlag;

This is clearly a good thing :) When you need to, however, you can always go "via" the underlying type (int in this case).

查看更多
迷人小祖宗
3楼-- · 2020-08-26 04:10

One reason is because C# currently (4.0) doesn't allow you to write an implicit operator overload (a cast) within an extension method (related question) for any type including an enumeration. It would be nice to cleanly convert to/from Int16 when integrating with a weakly typed database for instance or a weakly typed serialization format (binary writer).

查看更多
再贱就再见
4楼-- · 2020-08-26 04:22

What is Message.Msg defined as?

I'm betting it is Int32.

I'm also betting WindowsMessagesFlags is your type, but Message is from the framework.

Which means you're using your own enum with a framework-built object, and of course they are going to have some incompatibilities regarding types.

An enum is a strong type, not just a number, it is a number with a name in a context. This name, context, number, part isn't directly compatible with just numbers, and that's why you need to cast.

查看更多
登录 后发表回答