简体   繁体   中英

Method with Action Delegate Inheritance

Just for the sake of trying, I wanted to implement a code to incapsulate exceptions catching in a syntactic sugar (after reading a question on SO), so I attempted something like this:

class Program
{
    static void Main(string[] args)
    {
        TryCath(() =>
        {
            throw new Exception("BANANA");
        },
        DoSomethingWithException, DoSomethingWithCustomException);
    }

    public static void TryCath(Action argTry, params Action<Exception>[] catches)
    {
        try
        {
            argTry();
        }
        catch (Exception ex)
        {
            Type type = ex.GetType();
            catches.FirstOrDefault(x => x.Target.GetType() == type)?.Invoke(ex);
        }
    }

    public static Action<Exception> DoSomethingWithException = ex =>
    {
        Console.WriteLine(ex.ToString());
    };

    public static Action<CustomException> DoSomethingWithCustomException = ex =>
    {
        Console.WriteLine(ex.ToString());
    };
}

public class CustomException : Exception
{

}

As expected I get an error cause the method expects an Action<Exception> and I'm passing an Action<CustomException> too.

What if I want it to accept even CustomException which extends Exception ?

I normally see this written something like:

public class TryCatchBuilder
{
    private Exception exception;

    private TryCatchBuilder(Exception exception)
    {
        this.exception = exception;
    }

    public static TryCatchBuilder Try(Action action)
    {
        if (action is null)
            throw new ArgumentNullException(nameof(action));

        try
        {
            action();
            return new TryCatchBuilder(null);
        }
        catch (Exception e)
        {
            return new TryCatchBuilder(e);
        }
    }

    public TryCatchBuilder Catch<T>(Action<T> handler) where T : Exception
    {
        if (handler is null)
            throw new ArgumentNullException(nameof(handler));

        if (this.exception is T ex)
        {
            this.exception = null;
            handler(ex);
        }

        return this;
    }

    public void Finally(Action action)
    {
        if (action is null)
            throw new ArgumentNullException(nameof(action));

        action();
    }
}

And used as:

TryCatchBuilder
    .Try(() => throw new ArgumentNullException(""))
    .Catch((ArgumentNullException e) => { })
    .Catch((Exception e) => { })
    .Finally(() => { });

note the above does not handle the case where an exception occurs for which there is no handler!

... not that I support this pattern at all: use a normal try/catch statement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM