在兼容的枚举之间直接转换有多大风险?
How risky is a direct cast between compatible 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;
直接投射实际上工作正常,但这提出了一个对我来说非常重要的关于直接投射风险的问题。
在幕后,枚举只是整数(除非您另有说明)。所以从技术上讲,将枚举值转换为另一种没有该值字段的类型不是 "dangerous":
ServiceControllerStatus status = (ServiceControllerStatus)HostServiceStatus.Disabled;
status
的值将简单地为 8
。
危险当然已经存在于您的枚举声明的注释中:更改一个枚举的枚举值会导致您的应用程序仍然可以编译,但行为却大不相同甚至崩溃。
您可以参考源枚举以使这些枚举之间的关系更加明显:
public enum HostServiceStatus
{
NotInstalled = 0,
Stopped = ServiceControllerStatus.Stopped,
StartPending = ServiceControllerStatus.StartPending,
...
请注意,这些值是在编译时应用的;如果 ServiceControllerStatus
在 HostServiceStatus
之外的另一个程序集中声明,并且 ServiceControllerStatus
的 值 发生更改,这些更改将不会反映在 [=15] 中=] 直到你重新编译它。
我在两个枚举之间进行了以下直接转换:
_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;
直接投射实际上工作正常,但这提出了一个对我来说非常重要的关于直接投射风险的问题。
在幕后,枚举只是整数(除非您另有说明)。所以从技术上讲,将枚举值转换为另一种没有该值字段的类型不是 "dangerous":
ServiceControllerStatus status = (ServiceControllerStatus)HostServiceStatus.Disabled;
status
的值将简单地为 8
。
危险当然已经存在于您的枚举声明的注释中:更改一个枚举的枚举值会导致您的应用程序仍然可以编译,但行为却大不相同甚至崩溃。
您可以参考源枚举以使这些枚举之间的关系更加明显:
public enum HostServiceStatus
{
NotInstalled = 0,
Stopped = ServiceControllerStatus.Stopped,
StartPending = ServiceControllerStatus.StartPending,
...
请注意,这些值是在编译时应用的;如果 ServiceControllerStatus
在 HostServiceStatus
之外的另一个程序集中声明,并且 ServiceControllerStatus
的 值 发生更改,这些更改将不会反映在 [=15] 中=] 直到你重新编译它。