#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, конечно. Удачи!