C# 我应该在哪里试一试?

C# 我应该在哪里试一试?,c#,.net,exception-handling,try-catch,C#,.net,Exception Handling,Try Catch,学习记录错误。 这是贯穿整个项目的基本代码结构 有人告诉我,try块只能放在事件处理程序中。 但是在记录错误时,需要知道是哪种方法导致了错误。 因此,在这种情况下,我是否应该在AllIsFine()和SaveData()中保留try块。 如果是,那么它应该记录错误,还是只抛出 最佳/标准做法是什么 DataContext objDataContext = new DataContext(); protected void btn_Click(object sender, EventArgs e)

学习记录错误。 这是贯穿整个项目的基本代码结构

有人告诉我,try块只能放在事件处理程序中。 但是在记录错误时,需要知道是哪种方法导致了错误。 因此,在这种情况下,我是否应该在
AllIsFine()
SaveData()
中保留try块。 如果是,那么它应该记录错误,还是只抛出

最佳/标准做法是什么

DataContext objDataContext = new DataContext();
protected void btn_Click(object sender, EventArgs e)
{
  try
   {
     if(AllIsFine())
      {
        objDataContext.SaveData();
      }
   }
  catch(Exception ex)
   {
     //some handling
   }
}

private bool AllIsFine()
{
   //some code
}
编辑:当然,我们会尽力确保它不会引发异常,但不实用。我是这样看的。部署时,我唯一能访问的就是日志,需要获取尽可能多的信息。因此,在这种情况下(以及这种结构),您建议将try-catch保存在哪里

有人告诉我,只有在发生紧急情况时才需要放置try挡块 处理者

这不是真的。
有不同类型的异常,有些需要处理,有些应该抛出,有些应该捕获,有些不应该。请读

总结:

  • 您应该捕获可以对其进行处理的异常
  • 如果只想记录异常捕获、记录,然后使用
    throw
    而不是
    throw ex
    (它会重置调用堆栈)
  • 防止异常发生如果可以,请检查防止异常发生的条件(
    IndexOutorFrangeException
    NullPointerException
    ArgumentNullException
    ),而不是执行操作并捕获异常
  • 不要捕捉致命的异常;不管怎么说,你对他们无能为力,而试图让事情变得更糟
  • 修复您的代码,使其永远不会触发boneheaded异常–生产代码中永远不会发生“索引超出范围”异常
  • 通过调用那些抛出非异常的烦扰方法的“Try”版本,尽可能避免烦扰异常 情况。如果您无法避免调用令人烦恼的方法,请抓住它 令人烦恼的例外
  • 始终处理指示意外外部条件的异常;一般来说,预期是不值得或不实际的 每一个可能的失败。试着做手术,准备好 处理异常

try-catch语句由一个try块和一个或多个catch子句组成,这些子句为不同的异常指定处理程序

object o2 = null;
try
{
    int i2 = (int)o2;   // Error
}
在同一try-catch语句中可以使用多个特定catch子句。可以在catch块中使用throw语句来重新抛出catch语句捕获的异常。您可以捕获一个异常并抛出另一个异常。执行此操作时,请将捕获的异常指定为内部异常

catch (FileNotFoundException ex)
{
    // FileNotFoundExceptions are handled here.
}
catch (InvalidCastException ex) 
{
    // Perform some action here, and then throw a new exception.
    throw new YourCustomException("Put your error message here.", ex);
}
throw-ex基本上类似于从该点抛出异常,因此堆栈跟踪只会到达发出
throw ex的位置语句

但是,在记录错误时,需要知道使用哪种方法 导致错误的原因

您应该为此使用调用堆栈

尽可能地防止异常,不要捕捉它们,如果你想捕捉一个错误,就要捕捉一个特定的错误,我的意思是,不要捕捉异常,而是一些特定的,比如InvalidCastException


捕捉到错误后,您应该记录异常,但不要抛出异常来记录它。

我考虑了您的问题一段时间,即使它已经得到了回答,我还是想分享我的想法

一般的 在谈到异常处理时,您必须记住异常是什么: 当代码无法按预期运行时会发生异常,从而导致应用程序的行为/状态不一致。 这一思想将我们引向一条重要规则:不要捕获您无法处理的异常!异常系统提供安全性。设想一个连接到数据库的会计软件,该连接会引发异常。如果您只记录异常,而不向用户提供有关此情况的任何通知,则用户将开始使用软件,当他尝试保存时,数据将丢失

您知道,在何处处理异常非常重要:

  • 其中一些问题将由用户处理(通常在UI层中,例如MVVM/MVC中的视图),如示例中的数据库异常–只有用户可以决定是否需要数据库、连接字符串是否已更改或重试是否会解决问题
  • 其他的可以在发生的地方处理;例如,与某种硬件交互的代码通常实现具有某种重试或断路器逻辑的方法
建筑学 where决策也受体系结构的影响: 让我们回到数据库异常场景:您无法在UI层中处理特定异常,如MySQL特定异常(
MySqlException
),因为这会导致从视图层到特定模型层实现的边界,分层架构将被打破。但是,这不是主题,因为您的问题是关于记录异常的,但您应该记住这一点,并且可能会这样思考:捕获具体库的异常或那些属于特定层/依赖项的异常,并将其记录在那里,然后
抛出新的
,更通用(可能是自行创建的)例外情况。这些异常可以在视图层中处理并呈现给用户

实施 在哪里的问题也很重要。因为日志记录被视为一个贯穿各领域的问题。您可以考虑使用AOP框架,或者,正如我在一篇评论中所建议的那样,使用装饰器模式。您可以通过控件使用的基本反转来组合日志装饰器,通过将所有内容包装在
try-catch中,您的代码将更加干净