C# C语言中的忽略异常#

C# C语言中的忽略异常#,c#,exception,C#,Exception,在C#中,有没有更好的方法来忽略异常,而不是将其放在try-catch块中,在catch中什么都不做?我发现这种语法很麻烦。对于代码块,我不能简单地“标记”它,以便运行时知道哪些异常可以忽略吗?否。当异常发生时,它们沿调用堆栈向上移动,直到它们被catch块处理,或者整个过程终止。我认为没有办法避免异常,但您可以使用以下代码片段: public void IgnoreExceptions(Action act) { try { act.Invoke(); }

在C#中,有没有更好的方法来忽略异常,而不是将其放在try-catch块中,在catch中什么都不做?我发现这种语法很麻烦。对于代码块,我不能简单地“标记”它,以便运行时知道哪些异常可以忽略吗?

否。当异常发生时,它们沿调用堆栈向上移动,直到它们被
catch
块处理,或者整个过程终止。

我认为没有办法避免异常,但您可以使用以下代码片段:

public void IgnoreExceptions(Action act)
{
   try
   {
      act.Invoke();
   }
   catch { }
}
使用该方法看起来像:

IgnoreExceptions(() => foo());

另一个解决方案是使用AOP(面向方面编程)——有一个名为的工具,它使您能够创建一个属性,该属性将捕获特定程序集/类/方法中的所有异常,这更接近您要查找的内容。

您可以使用AOP来完成。例如,Postsharp将允许您轻松实现这样一个属性,该属性将跳过应用该属性的方法中的特定异常。没有AOP,我看不到任何好的方法来做这件事(如果我们假设有一个好的方法来做这件事;)

使用Postsharp,您可以通过以下方式装饰您的方法:

[IgnoreExceptions(typeof(NullReferenceException), typeof(StackOverflowException))]
void MyMethod() { ... }

一种方法是利用面向方面编程(AOP)。看一看。是一个在方法上使用异常属性的示例,这样,如果发生异常,您就可以不使用try..catch块来处理它

编辑:


啊,是的,Dror的建议也是很好的。我在企业库中看到过这样的例子。如果您不想在项目中使用第三方框架(即PostSharp),那就更好了。

我不知道有什么机制可以让您这样做

通常,忽略例外情况也被认为是一种非常糟糕的做法。提出例外情况(或应始终提出例外情况)有充分的理由;如果没有其他内容,您至少应该记录它们


如果您知道某一类型的异常对您的应用程序并不重要,那么可以使用事件来防止它崩溃,并检查该类型的异常。请注意,这仍然会将异常通过所有堆栈帧传播到最底层。

否。如果抛出异常,通常是发生的严重错误。你不想忽视它

相反,您应该重写代码以检查错误,并且只有当它确实失败时,才会抛出异常


例如,使用Int32.TryParse而不是Int32.Parse检查对象是否为有效整数。请记住,异常在强制转换时非常昂贵,许多强制转换会严重影响应用程序的性能。

空捕获块是一种非常难闻的代码气味。简而言之,你不应该追求一种速记的写作方式

规则1是,“如果你不能处理它,就不要抓住它。” 规则#1a是,“如果您没有实际处理异常,请重新抛出它。”


如果您只是想防止应用程序崩溃,那么在大多数情况下都可以使用更合适的机制。NET包括应用程序、调度程序和AppDomain级别的未处理异常事件,以及专门用于通知您后台线程上未处理异常的事件。在这个级别上,如果您无法验证应用程序的状态,您最好的选择可能是通知用户发生了错误并终止应用程序。

我想提供基于以前答案创建的扩展方法。希望它能帮助别人

/// <summary>
/// Extension methods for <see cref="Action"/> objects.
/// </summary>
public static class ActionExtensions
{
    /// <summary>
    /// Executes the <paramref name="action"/> and ignores any exceptions.
    /// </summary>
    /// <remarks>
    /// This should be used in very rare cases.
    /// </remarks>
    /// <param name="action">The action to execute.</param>
    public static void IgnoreExceptions(this Action action)
    {
        try { action(); }
        catch { }
    }

    /// <summary>
    /// Extends an existing <see cref="Action"/> so that it will ignore exceptions when executed.
    /// </summary>
    /// <param name="action">The action to extend.</param>
    /// <returns>A new Action that will ignore exceptions when executed.</returns>
    public static Action AddIgnoreExceptions(this Action action)
    {
        return () => action.IgnoreExceptions();
    }
}
publicstaticvoidignore(动作a),其中T:Exception
{
尝试
{
a();
}
渔获物(T)
{
}
}
使用:

    Ignore<InvalidOperationException>(() => foo());
Ignore(()=>foo());

@Dror,好主意。但是,请注意,您的代码包含一个微妙的错误:CLR实际上允许抛出任何值,而不仅仅是类型为
Exception
的对象(此限制仅由C#强制实施)。因此,您应该简单地重新编写
catch
块:
catch{}
;否则,某些异常可能会返回到调用方请参阅例如(大约向下两页)以获取参考。(我现在已经修复了它。我利用这个机会发现了您代码中的另一个拼写错误,我也已经更正了。希望您不介意。)为什么不使用act.Invoke(),而不是act.Invoke()?通常当出现异常时,程序会中断。因此,如果我使用try和catch,那么程序将运行catch而不是break?请查看下面的答案,以获得一个通用选项,您可以指定要忽略的异常。我知道忽略异常是一种糟糕的编程实践,但我的问题不是这样。我不认为有一个空的catch块有什么意义,因此我提出了一个问题。Jon skeet引用道:“如果你遇到异常严重影响性能的情况,那么除了性能之外,你在使用异常方面也会遇到问题。”吃异常就是处理异常。例如,您不希望日志框架抛出阻止业务功能工作的异常。基本上,您不希望您的主要任务因为可选的非必要代码中可能存在问题而失败。规则#1实际上应该是不要制定任何规则,因为这一切都要视情况而定。你总是需要了解你为什么做某事,以及它有什么含义。另外,你的回答以什么方式澄清了原来的问题?
    public static void Ignore<T>(Action a) where T : Exception
    {
        try
        {
            a();
        }
        catch (T)
        {
        }
    }
    Ignore<InvalidOperationException>(() => foo());