如何为枚举char(1)数据库字段实现C#enum?

好的,所以我有一个char(1)类型的数据库字段,它有少量可能的状态代码(例如’F’=失败,’U’=未知等)。 我想要一个与这些状态相对应的C#enum类。 我可以:

public enum StatusCode : byte { Unknown = (byte) 'U', Failure = (byte) 'F', // etc. } 

到现在为止还挺好。 但是在从数据库返回的DataTable中,列值是System.Data.SqlTypes.SqlString实例。 显然有一些问题从C#字符串(甚至是C#字符)转换为C#字节(因为C#char实际上是UTF-16代码点)。 但在这种情况下,我知道值被约束为一个小集合,如果此集合之外的值通过,代码应抛出exception。

考虑到这一点,这样做的最佳方法是什么? 从SqlString转换为字节是否安全? Convert.ToByte()会更好吗? 简单地使用开关/案例构造将值交叉到枚举中会更好吗?

我正在寻找“最好”的方法,不仅在获得正确的结果方面,而且在代码清晰度方面。 我想我也可以使用一些常量

 public const char UnknownStatus = 'U'; public const char FailureStatus = 'F'; 

但如果可能的话,我宁愿使用枚举。 有什么想法吗?

编辑:为了澄清我想要做什么,我希望在我的代码中经常使用这些值。 例如,我希望能够做到这样的事情:

 public void DoSomething(StatusCode currentStatus) { if(currentStatus == StatusCode.Failure) { throw new SomeException(); } switch(currentStatus) { case StatusCode.Unknown: // do something break; } } 

等等。 我特别想避免这样的事情:

 public void DoSomething(char currentStatus) { if(currentStatus == 'F') { // do something } } 

因为在这种情况下,我正在使用相当于“神奇数字”的地方。 特别是,这将使迁移到其他一些状态标记系统几乎不可能。 那有意义吗?

也许是一个“恒定”的对象?

 public sealed class StatusCode { private char value; public static readonly StatusCode Unknown = new StatusCode('U'); public static readonly StatusCode Failure = new StatusCode('F'); private StatusCode(char v) { value = v; } public override string ToString() { return value.ToString(); } } 

然后,在您的代码中,您可以像枚举一样使用它: StatusCode.Unknown 。 您还可以提供一种内部方法,将收到的值“解析”到StatusCode的对象中。

跳到编辑您是否尝试过此操作(这不会像您检查和评论时那样有效):

 public enum StatusCode : char { Failure = 'F', Unknown = 'U', ... } 

编辑 – 正确的解决方案
或者这个(甚至可以尝试使用结构):

 public sealed class StatusCode { public static readonly char Failure = 'F'; public static readonly char Unknown = 'U'; ... public char Value { get; set; } } 

您提供的代码将如下所示:

 public void DoSomething(StatusCode currentStatus) { if(currentStatus.Value == StatusCode.Failure) { throw new SomeException(); } switch(currentStatus.Value) { case StatusCode.Unknown: // do something break; } } 

如果您不喜欢使用Value属性,则可以始终在StatusCodechar类型之间实现隐式相等运算符。 在这种情况下,您的代码不会改变一点。

如果您使用的是.NET 2.0及更高版本,则可以使用通用字典实现此目的:

 Dictionary statusCode = new Dictionary(); statusCode.Add('U', "Unknown"); statusCode.Add('F', "Failure"); 

或者:

 Dictionary statusCode = new Dictionary(); statusCode.Add('U', StatusCode.Unknown); statusCode.Add('F', StatusCode.Failure); 

你可以访问给定代码的字符串表示,如下所示:

 string value = statusCode['A']; 

要么

 StatusCode myCode = statusCode['A']; 

等等。 您必须从数据库值或某种配置文件或其他东西填充该字典。

这样的事情对你有用吗?

 public Enum StatusCode : int{ [StringValue("U")] Unknown =0, [StringValue["F"] Failuer=1 } 

如果你有一个名为StatusCode的表,它包含一个整数主键,那么你可以使用它作为你的标识符,并将它挂钩到你的逻辑中。 在这种情况下,枚举将是最好的使用。 虽然我不确定这对你是否可行。

一种选择是使用与数据库中的值相同的名称设置枚举,例如:

 enum StatusCode { /// Unknown U = 0, /// Failure F, /// Etc E } 

然后使用静态方法将char值转换为枚举值

  private StatusCode CharToEnum(string statusCodeChar) { foreach (FieldInfo fi in typeof(StatusCode).GetFields()) { if (fi.Name == statusCodeChar) return (StatusCode)fi.GetValue(null); } return StatusCode.U; } 

我的男人简短又甜蜜..你需要的一切都是如此。 您不需要使用枚举,因为您不需要它为您的可能状态分配内部值,您已经知道状态的值。

 public sealed class StatusCode { public const string Unknown= "U"; public const string Failure= "F"; public const string Success= "S"; }