-3

I want to create a simple one-line try/catch without all the extra fluff:

// The extension class
public static class TryExFunc
{
    public static Exception TryEx<TResult> (this Func<TResult> func,
            out TResult result)
    {
        Exception error = null;
        try
        {
            result = func();
        }
        catch(Exception ex)
        {
            error = ex;
            result = default(TResult);
        }
        return error;
    }
}

// My Error Prone Function
public string SayHello() { throw new Exception(); }

// My Code 

// One (ok, two) line(s) to try/catch a function call... ew, works, but ew
string result;
Exception error = ((Func<string>)SayHello).TryEx<string>(out result);

// I want to do this!!!
string result;
Exception error = SayHello.TryEx<string>(out result);

Is there a way that I can do the bottom example? I'm still learning C# (coming from Lua and C++ background). Lua has a really nice function called 'pcall' that basically does the same thing. Thanks for any advice or suggestions you have!

:)

Dandruff
  • 21
  • 4
  • 2
    Another credit to the C# design team, they did make it really hard to write really bad code. – Hans Passant Mar 26 '15 at 22:34
  • Bad how? Because of the method cast to a generic "Func"? The extra "out" param that gets pushed to the stack? I am genuinely curious to figure out where this is inefficient (not knowing much about how this would get translated into CIL). – Dandruff Mar 26 '15 at 22:43
  • So what do you do if `error` is not null? How is that any better that using a normal try/catch? What if you want to handle a specific exception type but rethrow all others? – D Stanley Mar 26 '15 at 22:49
  • 2
    This code is designed to swallow up any old exception and return it as an `Exception` forcing the caller to do all sorts of type inspection and/or casting to get anything useful out of it - if they bother at all. Effectively this code is hiding error information that may be important. As a general rule you should only catch an exception if you can handle it. Don't catch it and then expect your caller to handle it. – Enigmativity Mar 26 '15 at 23:03

2 Answers2

2

You can't. Because the method group has no type. It's convertible to different delegate types. So you have to cast it to a delegate type before using it.

If you want to avoid cast you can do:

Func<string> sayHello = SayHello;
Exception error = sayHello.TryEx<string>(out result);
Selman Genç
  • 100,147
  • 13
  • 119
  • 184
0

It doesn't work as an extension method because in order to use an extension method, C# first needs to know the type to extend and, as @Selman22 stated, SayHello is a method group which may have other overloads, so we don't know the type.

It works as a method call because C# can see that the parameter required is a Func<T> and that SayHello is a valid Func<T>

The format below works to call the function.

string result;
Exception error = TryExFunc.TryEx(SayHello, out result);

and I do agree with @Enigmativity that you probably shouldn't be treating exceptions this way.

Grax32
  • 3,986
  • 1
  • 17
  • 32