блок try-catch

#c# #.net #exception-handling #try-catch

#c# #.net #исключение #попытка поймать

Вопрос:

У меня есть класс с разными методами, выполняющий то же самое, что и чтение файла. Я хочу использовать блок try-catch для обработки исключений. Я хочу спросить, есть ли какой-либо способ, чтобы все методы помещались в один блок try, поскольку каждый метод выдаст одно и то же исключение «файл не найден»..

Комментарии:

1. вы пробовали C # Generics??

2. @Furqan: Как дженерики помогут решить эту проблему?

Ответ №1:

Моим предпочтительным способом обработки этого было бы вызвать общий метод из всех них, чтобы каждый (по отдельности) выглядел как:

 try {
   // code
} catch(SomeExceptionType ex) {
   DoSomethingAboutThat(ex);
}
  

Однако вы также можете сделать это с помощью делегатов, т.Е.

 void Execute(Action action) {
    try {
       // code
    } catch(SomeExceptionType ex) {
       // do something
    }
}
  

и

 Execute(() => {open file});
  

Ответ №2:

Вы можете использовать этот метод для завершения действия с помощью метода расширения:

 public static class ActionExtensions
{
    public static Action WrapWithMyCustomHandling(this Action action)
    {
        return () =>
                {
                    try
                    {
                        action();
                    }
                    catch (Exception exception)
                    {

                        // do what you need 
                    }
                };
    }
}

public class DummyClass
{
    public void DummyMethod()
    {
        throw new Exception();
    }
}
  

а затем вызовите его, как показано ниже:

 DummyClass dummyClass = new DummyClass();
Action a = () => dummyClass.DummyMethod();
a.WrapWithMyCustomHandling()();
  

Таким образом, в принципе, вы можете обернуть любое действие этим.

Ответ №3:

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

 try
{
    .... your code
}
catch (SomeException e)
{
    ExceptionHandler(e);
}
  

Ответ №4:

Вам либо нужно добавить try catch вокруг содержимого каждого метода в вашем классе, либо подняться на один уровень области видимости, где вызываются ваши методы, и заключить их в try catch s.

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

Ответ №5:

Тот факт, что у вас есть «куча методов, делающих одно и то же», кажется источником проблемы. Можете ли вы превратить это в один метод?

Кроме того, вы могли бы обернуть блок try catch за пределы вызываемых методов. Таким образом, вызывающий объект может выполнять обработку исключений — методам просто нужно их выдавать.

Ответ №6:

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

Определение:

  private bool PerformActionOnFileStream(Action<FileStream> action, string path)
 {
      try
      {
           using(FileStream fileStream = new FileStream(@path, FileMode.Open))               
           {
                action(fileStream);
           }
      }
      catch(FileNotFoundException)
      {
           return false;
      }
 }
  

Использование:

  private void PrintContentOfFile(string path)
 {
      Action<FileStream> action = fileStream => PrintContentOfFileStream(fileStream);

      bool didPerformAction = PerformActionOnFileStream(action, path);
      if(!didPerformAction)
      {
           // Handle error.
      }
 }
  

Ответ №7:

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

Чтобы максимально приблизиться к тому, что вы ищете, без полного изменения способа ведения бизнеса, я бы предложил общий класс обработки ошибок в вашем решении и фрагмент, который расширяет стандартный фрагмент Try-Catch, но при этом передает вашему обработчику достаточно информации, чтобы вы могли выполнять определенную обработку исключений и пользовательских сообщений об ошибках.

Ваш пользовательский класс обработки ошибок должен иметь метод, подобный следующему:

public void HandleError(Sysem.Reflection.MethodBase MethodBase, Exception Exception);

Это или что-то подобное — это то, что я бы рекомендовал для вашего фрагмента.

     <?xml version="1.0" encoding="utf-8" ?>
    <CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
    <Header>
        <Title>try</Title>
        <Shortcut>try</Shortcut>
        <Description>Code snippet for try catch</Description>
        <Author>Microsoft Corporation</Author>
        <SnippetTypes>
            <SnippetType>Expansion</SnippetType>
            <SnippetType>SurroundsWith</SnippetType>
        </SnippetTypes>
    </Header>
    <Snippet>
        <Declarations>
            <Literal>
                <ID>expression</ID>
                <ToolTip>Exception type</ToolTip>
                <Function>SimpleTypeName(global::System.Exception)</Function>
            </Literal>
        </Declarations>
        <Code Language="csharp">
<![CDATA[try 
{           
    $selected$
}
catch (Exception ex)
{
        YourErrorHandler.HandleError(System.Reflection.MethodBase.GetCurrentMethod(), ex);
}]]>
        </Code>
    </Snippet>
</CodeSnippet>
  

Очевидно, вы можете расширить метод HandleError любым удобным для вас способом — в моих фрагментах для Интернета я передаю информацию о текущем пользователе, но вы можете использовать все, что пожелаете.

Желаю удачи!

Адам

Комментарии:

1. Я забыл упомянуть — если вы не привыкли использовать фрагменты, фрагмент try, вероятно, можно найти по адресу C:Program Файлы (x86) Microsoft Visual Studio 10.0 VC # Сниппеты 1033 Visual C #try.snippet. Чтобы использовать фрагмент, просто перейдите к своему коду, введите try и дважды нажмите tab. Если вы никогда раньше не использовали фрагменты, вы, вероятно, будете очень впечатлены… Я немного помешан на фрагментах, и у меня есть около 50 из них, которые я использую на регулярной основе — они действительно сильно повышают мою производительность — YMMV, конечно. Удачи!