兼容枚举之间的直接投射有多大风险?

时间:2015-03-12 07:34:59

标签: c# .net enums

我在两个枚举之间进行了以下直接演绎:

_viewModel.ServiceStatus = (HostServiceStatus)(HostController.Status);

枚举是:

public enum ServiceControllerStatus
{
    Stopped = 1,
    StartPending = 2,
    StopPending = 3,
    Running = 4,
    ContinuePending = 5,
    PausePending = 6,
    Paused = 7,
}
public enum HostServiceStatus
{
    // NB Do not ever change 1 to 6. These map directly to ServiceControllerStatus.
    NotInstalled = 0,
    Stopped = 1,
    StartPending = 2,
    StopPending = 3,
    Running = 4,
    ContinuePending = 5,
    PausePending = 6,
    Paused = 7,
    Disabled = 8
}

其中ServiceControllerStatus是CLR的一部分,并在System.ServiceProcess中定义。我怀疑这会很快改变。

我问,因为我发现了一个无关的错误,但在追踪它的过程中,我发现_viewModel.ServiceStatus仍然总是有零值。然后我用以下内容替换了直接演员,但却发现仍然存在错误:

var cs = HostController.Status;
HostServiceStatus hs;
Enum.TryParse(cs.ToString(), out hs);
_viewModel.ServiceStatus = hs;

直接演员实际上工作正常,但这对我来说是一个关于直接演员风险的非常重要的问题。

1 个答案:

答案 0 :(得分:1)

在引擎盖下,枚举只是整数(除非您另有说明)。因此从技术上讲,将枚举值转换为另一种没有该值字段的类型并不是危险的":

ServiceControllerStatus status = (ServiceControllerStatus)HostServiceStatus.Disabled;

status的价值就是8

当然危险在于你的枚举声明的注释:更改一个枚举的枚举值会导致你的应用程序仍然编译,但行为完全不同甚至崩溃。

您可以参考源枚举以使这些枚举之间的关系更加明显:

public enum HostServiceStatus
{
    NotInstalled = 0,
    Stopped = ServiceControllerStatus.Stopped,
    StartPending = ServiceControllerStatus.StartPending,
    ...

请注意,这些值在编译时应用;如果在ServiceControllerStatus以外的其他程序集中声明HostServiceStatus,并且ServiceControllerStatus已更改,则这些更改将不会反映在HostServiceStatus中你重新编译它。