好的,所以我有一个char(1)类型的数据库字段,它有少量可能的状态代码(例如'F'= Failure,'U'= Unknown等)。我想要一个与这些状态相对应的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代码点)。但在这种情况下,我知道值被约束为一个小集合,如果超出此集合的值,代码应该抛出异常。
考虑到这一点,最好的方法是什么?从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
}
}
因为在这种情况下,我正在使用相当于“魔术数字”的地方。特别是,这将使迁移到其他一些状态标记系统几乎是不可能的。这有意义吗?
答案 0 :(得分:5)
也许是一个“常数”对象?
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的对象。
答案 1 :(得分:1)
跳过要编辑您是否尝试过此操作(这在您检查和评论时无效):
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
属性,则始终可以在StatusCode
和char
类型之间实现隐式相等运算符。在这种情况下,您的代码不会改变一点。
答案 2 :(得分:0)
如果您使用的是.NET 2.0及更高版本,则可以使用通用字典实现此目的:
Dictionary<char,string> statusCode = new Dictionary<char,string>();
statusCode.Add('U', "Unknown");
statusCode.Add('F', "Failure");
或者:
Dictionary<char,StatusCode> statusCode = new Dictionary<char,StatusCode>();
statusCode.Add('U', StatusCode.Unknown);
statusCode.Add('F', StatusCode.Failure);
您可以访问给定代码的字符串表示形式,如下所示:
string value = statusCode['A'];
或
StatusCode myCode = statusCode['A'];
等等。您必须从数据库值或某种配置文件或其他东西填充该字典。
马克
答案 3 :(得分:0)
这样的事情对你有用吗?
public Enum StatusCode : int{
[StringValue("U")]
Unknown =0,
[StringValue["F"]
Failuer=1
}
答案 4 :(得分:0)
如果您有一个名为StatusCode的表,其中包含一个整数主键,那么您可以将其用作您的标识符,并将其挂钩到您的逻辑中。在这种情况下,枚举将是最好的使用。虽然我不确定这对你是否可行。
答案 5 :(得分:0)
一种选择是使用与数据库中的值相同的名称设置枚举,例如:
enum StatusCode
{
/// <summary>Unknown</summary>
U = 0,
/// <summary>Failure</summary>
F,
/// <summary>Etc</summary>
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;
}
答案 6 :(得分:0)
我的男人简短又甜蜜..你需要的一切都是如此。您不需要使用枚举,因为您不需要它为您的可能状态分配内部值,您已经知道状态的值。
public sealed class StatusCode
{
public const string Unknown= "U";
public const string Failure= "F";
public const string Success= "S";
}