2013-03-28 4 views
0

У меня есть несколько методов C#, которые я хочу обернуть в блок try-catch. Каждая функция будет иметь одинаковую логику для улова. Есть ли элегантный способ добавить декоратор к каждой из этих функций, чтобы все они были обернуты одним и тем же блоком try/catch? Я не хочу добавлять блок try/catch ко всем этим функциям.Тот же код catch для многих методов

Пример:

public void Function1(){ 
    try { 
    do something 
    }catch(Exception e) { 
     //a BUNCH of logic that is the same for all functions 
    } 
} 

public void Function2() { 
    try { 
    do something different 
    }catch(Exception e) { 
     //a BUNCH of logic that is the same for all functions 
    } 
} 
+0

Можете ли вы показать код ... –

+6

Почему бы не просто попробовать/поймать каждого и отправить исключение из общей статической функции ? –

+0

@JoelEtherton Как бы я это сделал, у вас есть пример? –

ответ

8

насчет некоторого функционального решения к этому? Заметьте, что я не проглатываю исключения и использую оператор throw;, который будет перебрасывать исключение, сохраняя исходную трассировку стека. Не забудьте проглотить исключения - это считается очень плохой практикой, а затем отладка кода очень ужасна.

void Main() 
{ 
    WrapFunctionCall(() => DoSomething(5)); 
    WrapFunctionCall(() => DoSomethingDifferent("tyto", 4)); 
} 

public void DoSomething(int v){ /* logic */} 

public void DoSomethingDifferent(string v, int val){ /* another logic */} 

public void WrapFunctionCall(Action function) 
{ 
    try 
    { 
     function(); 
    } 
    catch(Exception e) 
    { 
     //a BUNCH of logic that is the same for all functions 
     throw; 
    } 
} 

Если вам необходимо вернуть некоторое значение, подпись для WrapFunctionCall метода изменится

void Main() 
{ 
    var result = WrapFunctionCallWithReturn(() => DoSomething(5)); 
    var differentResult = WrapFunctionCallWithReturn(() => DoSomethingDifferent("tyto", 4)); 
} 

public int DoSomething(int v){ return 0; } 

public string DoSomethingDifferent(string v, int val){ return "tyto"; } 

public T WrapFunctionCallWithReturn<T>(Func<T> function) 
{ 
    try 
    { 
     return function(); 
    } 
    catch(Exception e) 
    { 
     //a BUNCH of logic that is the same for all functions 
     throw; 
    } 
} 
+0

Спасибо! Ваш код полезен! Я столкнулся с проблемой, когда, если все функции (кроме WrapFunctionCallWithReturn) принимают параметры ref, это приведет к ошибке: «Невозможно использовать параметр ref или out внутри анонимного метода ...». Мы решили это, сделав временное, а затем назначив его после вызова; есть ли способ использовать это решение с параметрами ref или out? – user3282085

+0

и с асинхронным? который вы предпочитаете: 'результат вар = ждут WrapFunctionCallWithReturn (() => DoSomething (5)),' 'результата вар = WrapFunctionCallWithReturn (() => ждут DoSomething (5)),' – fantastory

+0

я понимаю: 'var result = await WrapFunctionCallWithReturn (() => DoSomething (5));' необходим - ожидание должно быть внутри try catch – fantastory

2

Это комментарий Joel Etherton в перефразировать ответ. Обратите внимание, что это не лучшее решение (см. Ответ Илья Иванов для лучшего решения).
Но это просто и если я читаю ваш вопрос правильно, это именно то, что вы просили:

void errorHandling(Exception e) 
{ 
    // Your BUNCH of logic 
} 

public void Function1(){ 
    try { 
    do something 
    }catch(Exception e) { 
     errorHandling(e); 
    } 
} 

public void Function2() { 
    try { 
    do something different 
    }catch(Exception e) { 
     errorHandling(e); 
    } 
} 
+2

awesome username! – joshgo

Смежные вопросы