none
Why don't we have a try "shorthand"? RRS feed

  • Question

  • Sometimes I end up with something stupid like this:

    public bool MyMethod()
    {
       try
       {
          Client.Disconnect();
          return true;
       }
       catch { return false; }
    }

    In this case I want to see if some functionality works or not, and if it does I want a "thumbs up", if it's working as expected.

    "MyMethod()" is naturally executed from somewhere else, and maybe it lives in it's own class. This is messy, and tedious.

    Why isn't there already some "shorthand". I would, now and then, want something like this:

    Main ()
    {
       if (Attempt(Client.Disconnect()))
       {
          // Do something
       }
    }

    It's unusual for the actual return value to useful, but as a "fire-and-forget"-attempt to run a method, it's very efficient.

    I used "Client.Disconnect()", because sometimes, when doing multi-threading, forcing a "disconnect"-operation, is useful, and if it's an external library, there might be awful exception -implementation. e.g. you might get a "NullReferenceExeption", with no useful information, because there's not implemented a "Client.IsConnected", and when there's no connection to close, it asks for the connection, which is null and so... you get the point.

    This is almost a rant, but I miss this little quality of life -functionality, that wouldn't get my blood-pressure up, when I have to create my own "attemptors"

    -Frank 

    • Changed type BonnieBMVP, Moderator Sunday, December 30, 2018 2:42 AM need it to be a question in order to Propose an Answer
    Thursday, December 27, 2018 6:56 PM

All replies

  • Did you already try your own shorthand like this?

    static bool Attempt( Action a )

    {

        try

        {

            a();

            return true;

        }

        catch

        {

            return false;

        }

    }

     

    Usage:

    if( Attempt( () => Client.Disconnect() ) )

    {

     

    }

     

    or

     

    if( Attempt( Client.Disconnect ) )

    {

     

    }

    Friday, December 28, 2018 7:35 AM
  • Personally most people just create their own "safe" extension method. Since most companies have their own sets of libraries they just add it to their library code and now it can be used anywhere. The framework developers purposefully don't add "simple" methods to the framework because it increases complexity and testing for them. Foreach is a popular ask that they have justified as not needing in the past.

    There is also a strong view that "safe" methods are rare as you're ignoring potentially valid errors. For example an OOM or SO exception are bringing your app down whether you have a try-catch or not. But by "blindly" handling exceptions you may miss it. Still there are cases where it is useful. I personally tend to do one-off methods but here's a starter extension to help you.

    public static class ActionExtensions
    {
        public static ActionResult Try ( this Action action )
        {
            try
            {
                action();
                return ActionResult.Succeeded;
            } catch (Exception e)
            {
                return new ActionResult(e);
            };
        }
    
        public static ActionResult<T> Try<T> ( this Func<T> action )
        {
            try
            {
                return new ActionResult<T>(action());
            } catch (Exception e)
            {
                return new ActionResult<T>(e);
            };
        }
    }
    
    public struct ActionResult
    {
        public ActionResult ( Exception error )
        {
            Error = error;
        }
    
        public static readonly ActionResult Succeeded = new ActionResult();
    
        public bool Success => Error == null;
    
        public Exception Error { get; set; }
    }
    
    public struct ActionResult<T>
    {
        public ActionResult ( T result )
        {
            Error = null;
            Result = result;
        }
    
        public ActionResult ( Exception error )
        {
            Error = error;
            Result = default(T);
        }
    
        public bool Success => Error == null;
    
        public Exception Error { get; }
    
        public T Result { get; }
    }

    And how you might use it.

    class Program
    {
        static void Main ( string[] args )
        {
            Action willSucceed = () => Console.WriteLine("Hello");
            var result = willSucceed.Try();
            if (result.Success)
                Console.WriteLine("willSucceed was successful");
            else
                Console.WriteLine($"willSucceed failed with {result.Error}");
    
            Action willFail = () => throw new Exception("Failing");
            result = willFail.Try();
            if (result.Success)
                Console.WriteLine("willFail was successful");
            else
                Console.WriteLine($"willFail failed with {result.Error}");
    
            Func<DateTime> withResult = () => DateTime.Now;
            var typedResult = withResult.Try();
            if (typedResult.Success)
                Console.WriteLine($"withResult returned {typedResult.Result}");
            else
                Console.WriteLine($"withResult failed with {typedResult.Error}");
        }
    }


    Michael Taylor http://www.michaeltaylorp3.net

    Friday, December 28, 2018 3:55 PM
    Moderator