Reputation:
Is it possible to write a method like outType? TryDo(func, out exception, params)
that call func(arg1,arg2,arg3,...)
which params contains arg1,arg2,arg3,...
and then it return func return value and if any exception occurred return null and set the exception?
Can this be done better by another function signature?
for example I have
string Foo1(int i) { return i.ToString()}
void Foo2(int[] a) {throw new Exception();}
and then call
string t = TryDo(Foo1, out ex, {i});
TryDo(Foo2, out ex, {});
-----------Edited------------------
string t;
SomeClass c;
try
{
t = Foo1(4, 2, new OtherClass());
}
catch (Exception ex)
{
Log(ex);
if (/*ex has some features*/)
throw ex;
}
try
{
Foo2();
}
catch (Exception ex)
{
Log(ex);
if (/*ex has some features*/)
throw ex;
}
.
.
.
I want to make it like this.
string t = TryDo(Foo1, out ex, {4, 2, new OtherClass());
Examine(ex);
SomeClass c = TryDo(Foo2, out ex, {});
Examine(ex);
Upvotes: 0
Views: 2521
Reputation: 106796
I would avoid using out
parameters unless absolutely necessary.
Here is a quote from the Design Guidelines for Developing Framework Libraries:
Avoid using out or reference parameters.
Working with members that define out or reference parameters requires that the developer understand pointers, subtle differences between value types and reference types, and initialization differences between out and reference parameters.
You can instead create a return type that wraps the result of your call:
class CallResult<T> where T : class {
public CallResult(T result) { Result = result; }
public CallResult(Exception exception) { Exception = exception; }
public T Result { get; private set; }
public Exception Exception { get; private set; }
public Boolean IsSuccessful { get { return Exception == null; } }
}
Your method could then be implemented like this:
CallResult<T> TryDo<T>(Func<Object[], T> action, params Object[] args) where T : class {
try {
return new CallResult<T>(action(args));
}
catch (Exception ex) {
return new CallResult<T>(ex);
}
}
You can call it like this:
var callResult = TryDo<String>(Foo1, 4, 2, new OtherClass());
if (!callResult.IsSuccessful)
Examine(callResult.Exception);
However, if you intend to rethrow the exception in the Examine
method loosing the stacktrace you should really reconsider your approach.
Upvotes: 2
Reputation: 26717
if you are having too many try...catch(I can't understand why) you could go for AOP to centralize the Exception handling.
Below you can find a link that explains how to use it:
http://www.codeproject.com/KB/architecture/ExceptionHandlingWithAOP.aspx
Upvotes: 0
Reputation: 101130
What you are asking indicates that you have misunderstood how exceptions should be handled. Using try/catch everywhere can produce undesired results and make your application a whole lot harder to debug.
In short, only handle exceptions in the following cases:
SqlException
-> DataSourceException
)More info in my blog: http://blog.gauffin.org/2010/11/do-not-catch-that-exception/
Update
PLEASE do not use throw ex
. You are destroying the original call stack and therefore hiding where the exception was thrown originally. throw;
is your puppy. Use it everywhere and all the time.
Upvotes: 4
Reputation: 1278
Yes it is, but why would you want that?
int? TryDo(delegate d, out Exception e, params object[] par)
{
try
{
int res = d.Invoke(par);
e = null;
return res;
}
catch(Exception ex) { e = ex; return null; }
}
Upvotes: 0
Reputation: 2330
Yes, it's possible.
But why would you like to return a possible exception this way? You could throw further and process at the needed place.
Upvotes: 2