c# - 为什么在调试时而不是在运行时检查时会出现异常/从数据库映射枚举的最佳实践是什么

标签 c# database enums

考虑以下代码片段

public class Class1
{
    public enum TestEnum
    {
        Value1 = 1,
        Value2 = 2
    }
    public void TestCall()
    {
        /*some standard DB code returning an SqlDataReader...*/
        SqlDataReader rdr = com.ExecuteReader();
        Item item = new Item();

        /*original code*/
        /*Database "Type" is a varchar() field containing an integer, please dont ask why :)*/
        if (rdr["Type"].GetType() == typeof(DBNull))
        {
            item.Type = TestEnum.Value1;
        }
        else if ((string)rdr["Type"] == "1")
        {
            item.Type = TestEnum.Value2;
        }
        else if ((string)rdr["Type"] == "2")
        {
            item.Type = TestEnum.Value1;
        }
        else
        {
            item.Type = TestEnum.Value1;
        }

        /*suggested code*/
        item.Type = rdr["Type"] as TestEnum? ?? TestEnum.Value1; //<- default / null value to use
    }
}
public class Item
{
    public Class1.TestEnum Type;
}

在代码审查期间,我的一位同事指出我可以用一行(“建议代码”)替换级联 IF(“原始代码”)

虽然建议的代码运行得很好,但在检查“rdr[”Type”] as TestEnum?”时我得到了一个 NullReferenceException。在调试时。

我想知道这是否表明建议的代码存在潜在问题,将数据库值映射到枚举的首选方法是什么,一般来说您对这种代码有何看法。

最佳答案

建议的代码是错误的 - 它不会抛出异常,但总是计算为 TestEnum.Value1

为什么?读取器将值作为 object 返回。 as T? 运算符如果对象表示装箱 T 值,则运算符将评估为非空值。当对象像您的情况一样包含 string 时,或者即使是装箱的 int (枚举的基础类型),运算符 仍然是 TestEnum? 将评估为 null,因此表达式将命中 ?? TestEnum.Value1 条件。

很快,不要依赖这些技巧。如果您想改进该代码,请创建一个方法(如果需要,可以从其他地方重用):

static TestEnum ToTestEnum(object dbValue)
{
    TestEnum value;
    return Enum.TryParse(dbValue as string, out value) ? value : TestEnum.Value1;
}

然后把原来的代码改成这样

item.Type = ToTestEnum(rdr["Type"]);

关于c# - 为什么在调试时而不是在运行时检查时会出现异常/从数据库映射枚举的最佳实践是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44956682/

相关文章:

c# - 修改 Progress<T> 回调 Action

mysql - SQL查询,子查询减去子查询?

mysql - 什么时候将表从 MyISAM 更改为 InnoDb?

.net - 如何使用名称作为枚举已经被 vb.net 用作关键字

c# - 从特定数字获取枚举

java - 如何使用 id 检索枚举名称?

c# - LINQ to XML 简单查询

c# - 如何在 C# 中将正数或负数科学计数法转换为数字?

c# - 在 .NET 中保留文件权限

python - 如何为 Django 模型中的用户名匹配数据库中的确切大小写?