Выделите общий код между общими функциями - PullRequest
0 голосов
/ 04 января 2019

У меня есть две функции в классе. Единственными отличиями являются параметр функции (один принимает Func с X, а другой Y) и строки, отмеченные звездочками.

Есть ли способ выделить эти две строки звездочками или иметь общую функцию или переписать функции так, чтобы операторы try, catch и последние несколько операторов записывались только один раз?

Цель здесь - минимизировать дублирование кода.

public T Do<T>(Func<X, T> something)
{
    try
    {
        var manager = CoreInfrastructure.GetManager(Prefix, Config.Param1, Config.Param2); //******
        if (manager != null) return something(manager);
        LoggingHandler.LogWarning(LogTitle, $"manager ({this}) is null.");
    }
    catch (MyException exp)
    {
        ExceptionHandler.HandleRecoverableException(exp, LogTitle,
            $"query on manager ({this}) failed.");
    }

    var msg = $"failed to query using manager ({this})!";
    LoggingHandler.LogCritical(LogTitle, msg);
    throw new MyException(msg);
}


public T Do<T>(Func<Y, T> something)
{
    try
    {
        var manager = CoreInfrastructure.GetManager(Prefix, Config.Param3); //******
        if (manager != null) return something(manager);
        LoggingHandler.LogWarning(LogTitle, $"manager ({this}) is null.");
    }
    catch (MyException exp)
    {
        ExceptionHandler.HandleRecoverableException(exp, LogTitle,
            $"query on manager ({this}) failed.");
    }

    var msg = $"failed to query using manager ({this})!";
    LoggingHandler.LogCritical(LogTitle, msg);
    throw new MyException(msg);
}

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Мы можем создать частную функцию, которая выполняет большую часть работы, и заставить существующие методы просто обернуть ее соответствующим образом:

private T DoInternal<T>(Func<X> getManager, Func<X, T> something)
{
    try
    {
        var manager = getManager();
        if (manager != null) return something(manager);
        LoggingHandler.LogWarning(LogTitle, $"manager ({this}) is null.");
    }
    catch (MyException exp)
    {
        ExceptionHandler.HandleRecoverableException(exp, LogTitle,
            $"query on manager ({this}) failed.");
    }

    var msg = $"failed to query using manager ({this})!";
    LoggingHandler.LogCritical(LogTitle, msg);
    throw new MyException(msg);
}
public T Do<T>(Func<X, T> something)
{
    return DoInternal(()=> CoreInfrastructure.GetManager(Prefix, Config.Param1, Config.Param2), something);
}
public T Do<T>(Func<Y, T> something)
{
    return DoInternal(()=> CoreInfrastructure.GetManager(Prefix, Config.Param3),something);
}

Конечно, getManager может потребоваться дальнейшая параметризация, если есть общиефункциональные возможности там (например, позволяют DoInternal передавать Prefix?).

(Кроме того, все приведенные выше объявления выглядят немного подозрительно, поскольку они параметризованы только в T, а не X и Y.Там могут потребоваться некоторые дополнительные настройки)

0 голосов
/ 04 января 2019

Создание общего метода, который принимает менеджер и функцию

    public T Do<T, TManager>(TManager manager, Func<TManager, T> something)
    {
        try
        {
            if (manager != null) return something(manager);
            LoggingHandler.LogWarning(LogTitle, $"manager ({this}) is null.");
        }
        catch (MyException exp)
        {
            ExceptionHandler.HandleRecoverableException(exp, LogTitle,
                $"query on manager ({this}) failed.");
        }

        var msg = $"failed to query using manager ({this})!";
        LoggingHandler.LogCritical(LogTitle, msg);
        throw new MyException(msg);
    }

    public void DoAll<T>(Func<X, T> somethingX, Func<Y, T> somethingY)
    {
        Do(CoreInfrastructure.GetManager(Prefix, Config.Param1, Config.Param2), somethingX);
        Do(CoreInfrastructure.GetManager(Prefix, Config.Param3), somethingY);
    }

Как упомянул Damien_The_Unbeliever, если источником создания менеджера может быть MyException, вы можете добавить Func<TManager> вместо менеджера TManager:

    public T Do<T, TManager>(Func<TManager> managerCreate, Func<TManager, T> something)
    {
        try
        {
            TManager manager = managerCreate();
            if (manager != null) return something(manager);
            LoggingHandler.LogWarning(LogTitle, $"manager ({this}) is null.");
        }
        catch (MyException exp)
        {
            ExceptionHandler.HandleRecoverableException(exp, LogTitle,
                $"query on manager ({this}) failed.");
        }

        var msg = $"failed to query using manager ({this})!";
        LoggingHandler.LogCritical(LogTitle, msg);
        throw new MyException(msg);
    }

    public void DoAll<T>(Func<X, T> somethingX, Func<Y, T> somethingY)
    {
        Do(() => CoreInfrastructure.GetManager(Prefix, Config.Param1, Config.Param2), somethingX);
        Do(() => CoreInfrastructure.GetManager(Prefix, Config.Param3), somethingY);
    }

Вы можете пойти дальше и заменить Func<TManager> параметризованной функцией, где вы передаете Prefix и Config

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...