兼容枚举之间的直接强制转换的风险有多大



我在两个枚举之间有以下直接转换:

_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;
直接演员实际上

工作正常,但这对我来说提出了关于直接演员风险的相当重要的问题。

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

ServiceControllerStatus status = (ServiceControllerStatus)HostServiceStatus.Disabled;

然后,status的值将简单地8

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

您可以引用源枚举以使这些枚举之间的关系更加可见:

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

请注意,这些值在编译时应用;如果在 HostServiceStatus 以外的另一个程序集中声明ServiceControllerStatus,并且更改了ServiceControllerStatus的值,则在重新编译之前,这些更改不会反映在HostServiceStatus中。

最新更新