Z.V
Z.V

Reputation: 1461

Generic Function wrapper

I have many functions with different content but the parameters and try catch inside is almost similar. Is there anyway to wrap the function up so that can reduce redundant codes.

ResponseStatus GetPotatoList(GetPotatosRequest requestParam, out GetPotatosResponse response, out ResponseErrorType errorType)
{
    ResponseStatus status = ResponseStatus.Fail;
    response = new GetPotatosResponse();

    //To Do

    try
    {

        //To Do

        status = ResponseStatus.Success;
    }
    catch(CustomException ex)
    {
        errorType = ResponseErrorType.CustomError;
    }
    catch(TimeoutException ex)
    {
        errorType = ResponseErrorType.Timeout;
    }
    catch(Exception ex)
    {
        errorType = ResponseErrorType.GeneralFailure;
    }

    return status;
}

Upvotes: 4

Views: 11041

Answers (3)

Peter L
Peter L

Reputation: 3343

I needed to provide functionality before and after invoking an original method whose signature didn't vary much.

I used Func<..>...

    public static Func<string, string> Hello = name => "hello " + name;

    public static string Hello2(string name) => wrap(Hello)(name);

    // This does NOT retain the name of the arg for hints in the IDE 
    public static Func<string, string> Hello3 = name => wrap(Hello)(name);

    private static Func<string, T> wrap<T>(Func<string, T> orig)
    {
        return name => orig(name.ToUpper());
    } 

Upvotes: 1

Janne Matikainen
Janne Matikainen

Reputation: 5121

Instead using Action you should maybe use a function that will take the request as the parameter and return your response object, then you can take benefit of generics to make the call and then handle specific cases. Also returning tuple or some generic type for the Result might be a good idea instead of using out parameters.

public static Tuple<TResponse, ResponseStatus, ResponseErrorType> GetResponse<TRequest, TResponse>(Func<TRequest, TResponse> action, TRequest request)
{
    var status = ResponseStatus.Fail;
    var errorType = ResponseErrorType.None;
    var response = default(TResponse);

    try
    {
        response = action(request);
        status = ResponseStatus.Success;
    }
    catch (CustomException ex)
    {
        errorType = ResponseErrorType.CustomError;
    }
    catch (TimeoutException ex)
    {
        errorType = ResponseErrorType.Timeout;
    }
    catch (Exception ex)
    {
        errorType = ResponseErrorType.GeneralFailure;
    }

    return new Tuple<TResponse, ResponseStatus, ResponseErrorType>(response, status, errorType);
}

Upvotes: 0

Kilazur
Kilazur

Reputation: 3188

You can pass an Action to your method.

ResponseStatus GetPotatoList(Action action1, Action action2, GetPotatosRequest requestParam, out GetPotatosResponse response, out ResponseErrorType errorType)
{
    ResponseStatus status = ResponseStatus.Fail;
    response = new GetPotatosResponse();

    action1();

    try
    {
        action2();
        status = ResponseStatus.Success;
    }
    catch(CustomException ex)
    {
        errorType = ResponseErrorType.CustomError;
    }
    catch(TimeoutException ex)
    {
        errorType = ResponseErrorType.Timeout;
    }
    catch(Exception ex)
    {
        errorType = ResponseErrorType.GeneralFailure;
    }

    return status;
}

Then use it:

var response = GetPotatoList(
    () => doSomething(),
    () => doSomethingElse(),
    requestParam,
    out response,
    out errorType);

Upvotes: 10

Related Questions