Игнорировать исключение в C # - PullRequest
22 голосов
/ 06 февраля 2011

Есть ли лучший способ игнорировать исключение в C #, чем поместить его в блок try catch и ничего не делать в catch?Я считаю этот синтаксис громоздким.Для кодового блока я не могу просто «пометить» его таким образом, чтобы среда выполнения знала, какими исключениями пренебрегать?

Ответы [ 9 ]

27 голосов
/ 06 февраля 2011

Я не думаю, что есть способ избежать исключения, но вы можете использовать следующий фрагмент кода:

public void IgnoreExceptions(Action act)
{
   try
   {
      act.Invoke();
   }
   catch { }
}

Использование метода выглядит следующим образом:

IgnoreExceptions(() => foo());

Другим решением является использование AOP (Aspect Oriented Programming) - есть инструмент под названием PostSharp , который позволяет вам создать атрибут, который будет перехватывать все исключения в конкретной сборке / классе / методе, который ближе к что вы ищете.

6 голосов
/ 06 февраля 2011

Вы можете сделать это с помощью АОП.Например, Postsharp позволит вам легко реализовать такой атрибут, который пропустит определенные исключения в методах, к которым вы применили такой атрибут.Без АОП я не вижу никакого хорошего способа сделать это (если мы предположим, что есть хороший способ сделать такие вещи;)).

С Postsharp вы сможете украсить свои методы следующим образом:

[IgnoreExceptions(typeof(NullReferenceException), typeof(StackOverflowException))]
void MyMethod() { ... }
4 голосов
/ 06 февраля 2011

Один из способов - воспользоваться аспектно-ориентированным программированием (AOP). Посмотрите на PostSharp . Здесь - пример использования атрибута исключения в методе, чтобы в случае возникновения исключения вы могли иметь дело с ним без блока try..catch.

EDIT:

Ах да, предложение Дрора тоже хорошее. Я видел примеры этого в Enterprise Library. Было бы лучше, если вы не хотите, чтобы в вашем проекте была сторонняя платформа (например, PostSharp).

2 голосов
/ 22 июня 2015

Я хотел добавить методы расширения, которые я создал, основываясь на предыдущих ответах. Надеюсь, это кому-нибудь поможет.

/// <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();
    }
}

И юнит-тесты:

[TestClass]
public class ActionExtensionsTests
{
    [TestMethod]
    public void IgnoreException()
    {
        Action justThrow = () => { throw new InvalidOperationException(); };
        justThrow.IgnoreExceptions();
    }
    [TestMethod]
    public void AddIgnoreException()
    {
        Action justThrow = () => { throw new InvalidOperationException(); };
        var newAction = justThrow.AddIgnoreExceptions();
        newAction();
    }
}
2 голосов
/ 06 февраля 2011

Я не знаю ни одного механизма, который позволил бы вам сделать это.

Как правило, игнорирование исключений также считается очень плохой практикой. Исключения (или всегда должны быть) подняты по уважительной причине; если ничего другого, вы должны хотя бы зарегистрировать их.

Если вы знаете, что определенный тип исключения не является критичным для вашего приложения, вы можете предотвратить его аварийное завершение, используя событие Application.UnhandledException , проверяя наличие такого рода исключения. Обратите внимание, что это все равно будет распространять исключение по всем фреймам стека до самого низа.

1 голос
/ 06 февраля 2011

Нет.Когда возникают исключения, они перемещаются обратно вверх по стеку вызовов либо до тех пор, пока они не будут обработаны блоком catch, либо весь процесс не завершится.

0 голосов
/ 01 июля 2017
    public static void Ignore<T>(Action a) where T : Exception
    {
        try
        {
            a();
        }
        catch (T)
        {
        }
    }

Для использования:

    Ignore<InvalidOperationException>(() => foo());
0 голосов
/ 07 февраля 2011

Пустые блоки улова - очень вонючий запах кода. Короче говоря, вы не должны использовать сокращенный способ их написания.

Правило № 1: «Не лови, если не справишься». Правило № 1а гласит: «Если вы на самом деле не обрабатывали исключение, перебросьте его».

Если вы просто пытаетесь предотвратить сбой приложения, в большинстве случаев есть более подходящие механизмы. .NET включает события UnhandledException на уровнях Application, Dispatcher и AppDomain, а также события, предназначенные для уведомления вас о необработанных исключениях в фоновых потоках. На этом уровне, если вы не можете проверить состояние своего приложения, лучшим вариантом может быть уведомление пользователя о том, что произошло что-то плохое, и завершение работы приложения.

0 голосов
/ 06 февраля 2011

Нет. Если выдается исключение, это, как правило, критическая ошибка, которая произошла. Вы не хотите игнорировать это.

Вместо этого вам следует переписать свой код, чтобы проверить наличие ошибок, и только в случае его сбоя выдается исключение.

Например, используя Int32.TryParse вместо Int32.Parse, чтобы проверить, является ли объект допустимым целым числом. Помните, что исключения являются очень дорогими при их приведении, и многие приведенные типы серьезно влияют на производительность вашего приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...