C# 是否可以从故障点继续运行代码?

C# 是否可以从故障点继续运行代码?,c#,.net,database,oracle,exception-handling,C#,.net,Database,Oracle,Exception Handling,好的,我有一些非常简单的代码,我将在下面发布。本质上,我有一个到数据库的连接,我想将查询中的列子集映射到一个特定的类。问题是这些值可能为空 我想知道,如果在某一行抛出异常,我们是否可以从下一行恢复整个块 所以,如果下面的代码要执行,第6行捕捉到一个错误。是否有一种优雅的方法来捕获异常并使代码在第7行继续运行。从本质上说,第6行似乎从未执行过 private static Column MapTableToColumn(OracleDataReader reader){ Colu

好的,我有一些非常简单的代码,我将在下面发布。本质上,我有一个到数据库的连接,我想将查询中的列子集映射到一个特定的类。问题是这些值可能为空

我想知道,如果在某一行抛出异常,我们是否可以从下一行恢复整个块

所以,如果下面的代码要执行,第6行捕捉到一个错误。是否有一种优雅的方法来捕获异常并使代码在第7行继续运行。从本质上说,第6行似乎从未执行过

 private static Column MapTableToColumn(OracleDataReader reader){
        Column c = new Column();
        c.ColumnName = Convert.ToString(reader["COLUMN_NAME"]);
        c.DataType = Convert.ToString(reader["DATA_TYPE"]);
        c.DataLength = Convert.ToInt32(reader["DATA_LENGTH"]);
        c.DataPrecision  = Convert.ToInt32(reader["Data_Precision"]);//<---Line 6
        c.DataScale = Convert.ToInt32(reader["Data_scale"]);//<--- Line 7
        c.AllowDBNull = Convert.ToBoolean(reader["ALLOW_DB_NULL"]);
        c.IsReadOnly = Convert.ToBoolean(reader["IS_READ_ONLY"]);
        c.IsLong = Convert.ToBoolean(reader["IS_LONG"]);
        c.IsKey = Convert.ToBoolean(reader["IS_KEY"]);
        c.KeyType = Convert.ToString(reader["KEY_TYPE"]);
        c.IsUnique = Convert.ToBoolean(reader["IS_UNIQUE"]);
        c.Description = Convert.ToString(reader["DESCRIPTION"]);
        return c;
    }
私有静态列MapTableToColumn(OracleDataReader){
列c=新列();
c、 ColumnName=Convert.ToString(读卡器[“COLUMN_NAME]”);
c、 DataType=Convert.ToString(读卡器[“数据类型]);
c、 DataLength=Convert.ToInt32(读卡器[“数据长度]);

c、 DataPrecision=Convert.ToInt32(读卡器[“Data_Precision”])/不,您所要求的在c语言中是不可能的

相反,解决这个问题的正确方法是使用更好的解析方法,这些方法一开始不会抛出异常。如果输入值可以为null,则使用可以接受null值的解析方法

您可能需要做的第一件事是为int/bool字段使用可为null的类型,以便支持null值。接下来,您需要创建自己的方法来解析int/bool。如果输入为null,则返回null;如果输入为null,则使用
int.TryParse
bool.TryParse
(或
作为
,如果输入的类型正确,只需转换为
对象


然后,通过使用这些方法,而不是
Convert
,您将不会首先抛出异常(即使它可以工作,您也不应该在这里这样做,因为异常用于异常情况,而不是预期的控制流)。

不,您所要求的在C中是不可能的

相反,解决这个问题的正确方法是使用更好的解析方法,这些方法一开始不会抛出异常。如果输入值可以为null,则使用可以接受null值的解析方法

您可能需要做的第一件事是为int/bool字段使用可为null的类型,以便支持null值。接下来,您需要创建自己的方法来解析int/bool。如果输入为null,则返回null;如果输入为null,则使用
int.TryParse
bool.TryParse
(或
作为
,如果输入的类型正确,只需转换为
对象

然后,通过使用这些方法,而不是
Convert
,您将不会首先抛出异常(即使它可以工作,您也不应该在这里这样做,因为异常是针对异常情况的,而不是预期的控制流)。

检查IsDBNull

读卡器对每个SQL数据类型都有方法
比如说

如果数据以字符串(char,nchar)形式存在于SQL中,则首先检查null,然后检查TryParse
比如说

顺序位置更快
这是可为空的Int16的示例

Int16? ID; 
ID = rdr.IsDBNull(4) ? (Int16?)null : rdr.GetInt16(4);
如果你想要一个默认值

Int16 ID; 
ID = rdr.IsDBNull(4) ? 0 : rdr.GetInt16(4);
检查IsDBNull

读卡器对每个SQL数据类型都有方法
比如说

如果数据以字符串(char,nchar)形式存在于SQL中,则首先检查null,然后检查TryParse
比如说

顺序位置更快
这是可为空的Int16的示例

Int16? ID; 
ID = rdr.IsDBNull(4) ? (Int16?)null : rdr.GetInt16(4);
如果你想要一个默认值

Int16 ID; 
ID = rdr.IsDBNull(4) ? 0 : rdr.GetInt16(4);

您需要对每个变量赋值进行try/catch,并且在尝试之前需要初始化所有
实例值。这将相对较慢

至于基于行号的反射:我不会依赖行号,因为对代码进行一个简单、无辜的更改就会完全放弃它

我会特别检查空值。如果您希望使用空值,则很难将其称为“异常”。实现这一点的方法是。它采用列索引(而不是列名),因此您需要使用以下方法解析索引:


您需要对每个变量赋值进行try/catch,并且在尝试之前需要初始化所有
实例值。这将相对较慢

至于基于行号的反射:我不会依赖行号,因为对代码进行一个简单、无辜的更改就会完全放弃它

我会特别检查空值。如果您希望使用空值,则很难将其称为“异常”。实现这一点的方法是。它采用列索引(而不是列名),因此您需要使用以下方法解析索引:

如果异常是预期的,则它不是异常。永远不会捕获空引用异常。空引用异常是一个错误。相反,请编写代码以避免该错误

您可以轻松编写测试null的帮助器方法,或者使用诸如
Int32.TryParse
之类的方法来处理格式错误的字符串。

如果异常是预期的,那么它就不是异常。永远不会捕获null引用异常。null引用异常是一个错误。相反,编写代码以避免该错误。


您可以轻松编写测试null的帮助器方法,或者使用诸如
Int32.TryParse
之类的方法来处理格式错误的字符串。

只需测试isnull。检查
null
/
DBNull.Value
似乎比异常处理更合适。只需测试isnull。检查
null
/
DBNull.Value
似乎比异常处理更合适。在数据读取器的情况下,它实际上不是解析的情况,而是检查它之前是否为nullcasting@MarcGravell不清楚是哪个,这就是为什么我不喜欢使用
Convert
。我们不知道他是在解析还是在强制转换