C# 例外处理最佳做法

C# 例外处理最佳做法,c#,C#,我想知道哪种方法是进行异常处理的最佳方法,因为在我的Try语句中,我有很多验证,如果我在那里得到一些Exception,我的Catch语句可以告诉我发生了什么,但是我如何知道异常发生在哪个字段中 示例代码 try { // If I get a Exception when converting to number, // I will understand the error // but how could I know where in my `Try` statem

我想知道哪种方法是进行异常处理的最佳方法,因为在我的
Try
语句中,我有很多验证,如果我在那里得到一些
Exception
,我的
Catch
语句可以告诉我发生了什么,但是我如何知道
异常发生在哪个字段中

示例代码

try
{
   // If I get a Exception when converting to number, 
   // I will understand the error 
   // but how could I know where in my `Try` statement was the error ?
   int valor = Convert.ToInt32(xmlnode[i].ChildNodes.Item(2).InnerText.Trim());
   // A Lot of another validations here
}
Catch(Exception e)
{
      this.LogInformation(e.Message);
}

除非创建了不同的异常(即不同的类),否则您将需要使用不同的try捕获来处理它

通常,您可以执行以下操作:

try
{
   // If I get a Exception when converting to number, 
   // I will understand the error 
   // but how could I know where in my `Try` statement was the error ?
   int valor = Convert.ToInt32(xmlnode[i].ChildNodes.Item(2).InnerText.Trim());
   // A Lot of another validations here
}
Catch(IOException ioe) {
      // Handle, log
}
Catch(ArgumentNullException ane) {
      // Handle, log
}
Catch(Exception e)
{
      // Handle, log and potentially rethrow
}
您还可以在try块中有单独的try-catch(我认为这是大多数人会做的事情)或嵌套的try-catch:

不确定这是否有帮助。

移动尝试..捕捉内部循环。这样,您就可以知道到底是哪一项导致了异常

foreach(var xmlNode in nodes)
{
    try    
    {
       //
       int valor = Convert.ToInt32(xmlNode.ChildNodes.Item(2).InnerText.Trim());
       // A Lot of another validations here
    }
    catch(Exception e)
    {
       LogInformation(e.Message); // current item is xmlNode
       return;
    }
}

如果不确定该值,请不要使用Convert.ToInt32。请改用Int32.TryParse:

int valor;
if (Int32.TryParse(xmlnode[i].ChildNodes.Item(2).InnerText.Trim(), out valor))
{
     // Worked! valor contains value
}
else
{
    // Not a valid Int32
}
此外,您不应该使用异常来捕获验证错误。验证代码应该计算值是否正确,而不是在值不正确时失败。验证类应该同时接收有效和无效数据作为输入。因为您希望输入无效,所以不应该在输入无效时捕获异常


提出一个测试,检查数据是否有效,并返回true或false。几乎所有的数值类型都有一个如上所述的TryParse方法。对于其他验证方法的自定义规则,请提出一个规范,精确定义有效和无效输入,然后编写一个方法来实现该规范。

如果您尝试解析的值极有可能不可解析,因此这不是一个例外情况,维斯。不应视为例外情况

在这种情况下,存在
TryParse
,它允许您确定该值对于解析无效:

int valor;
if(int.TryParse(xmlnode[i].ChildNodes.Item(2).InnerText.Trim(), out valor))
{
  // "valor" is sucessfully parsed
}
else
{
  // invalid parse - do something with that knowledge
}

最好的做法是在将字符串转换为数字时,不要使用
Try-Catch
。因此,您应该使用
TryParse
方法,如
int.TryParse

// note that here is also a possible error-source
string valorToken = xmlnode[i].ChildNodes.Item(2).InnerText.Trim(); 
int valor;
if(!int.TryParse(valorToken, out valor))
{
    // log this
}
// else valor was parsed correctly

除此之外,如果您想提供准确的错误消息,您必须使用多个
try catch
或处理不同的异常类型(最常见的
异常类型必须是最后一个)。

对于所有
转换
,如果您不能100%确定它们是否有效,则应改用
TryParse
。例如,对于Int32:但这只是一个例子,我有很多验证,不仅仅是
Convert.toInt32
。我只想在Catch语句中找到我的代码停止的地方。但这只是一个例子,我有很多验证,不仅仅是
Convert.toInt32
。我只想在Catch语句中找到我的代码停止的地方。@Lucas_Santos-我的回答也只是一个例子。你应该为你认为可能失败的一切做类似的事情。你不需要用
int valor=0
赋值,用
int valor
声明就足够了@安德烈亚斯尼德米尔-学究。
int
被隐式设置为零,我只是显式的。@Jamiec这是不正确的。。。声明和赋值之间有区别。。。声明变量只是为了获得轻微的性能提升:)您的标题提到了异常和最佳实践。如果只是数字解析,那么我会选择托比的答案
int valor;
if(int.TryParse(xmlnode[i].ChildNodes.Item(2).InnerText.Trim(), out valor))
{
  // "valor" is sucessfully parsed
}
else
{
  // invalid parse - do something with that knowledge
}
// note that here is also a possible error-source
string valorToken = xmlnode[i].ChildNodes.Item(2).InnerText.Trim(); 
int valor;
if(!int.TryParse(valorToken, out valor))
{
    // log this
}
// else valor was parsed correctly