C# способ записи Func с возвращением void

у меня есть следующие две функции, которые почти идентичны, единственная разница заключается в том, что один использует func, другой action. И я хочу объединить их в одну функцию, если это возможно.

    private static void TryCatch(Action action)
    {
        try
        {
            action();
        }
        catch (Exception x)
        {
            Emailer.LogError(x);
            throw;
        }
    }

    private static TResult TryCatch<TResult>(Func<TResult> func)
    {
        try
        {
            return func();
        }
        catch (Exception x)
        {
            Emailer.LogError(x);
            throw;
        }
    }

3 ответов


объединение этих двух в одну функцию в C# действительно невозможно. The void В C# и CLR просто не является типом и, следовательно, имеет другую семантику возврата, чем функция Non-void. Единственный способ правильно реализовать такой шаблон-обеспечить перегрузку для делегатов void и Non-void

ограничение CLR не означает, что это невозможно сделать на каждом языке CLR. Это просто невозможно в языках, которые используют void для представления функции, которая возвращает no ценности. Этот шаблон очень выполним в F#, потому что он использует Unit вместо void для методов, которые не возвращают значение.


вы могли бы использовать свой второй, Func<T> версия, чтобы реализовать Action метод, просто обернув действие в лямбду. Это устраняет часть дублированного кода.

private static void TryCatch(Action action)
{
    Func<object> fun => 
       {
           action();
           return null;
       };
    TryCatch(fun);
}

это, как говорится, есть дополнительные накладные расходы, связанные с этим, поэтому лично я, вероятно, оставлю его так, как вы в настоящее время его реализовали (особенно учитывая, насколько коротка и проста ваша оригинальная версия в этом случае).


Я делаю это, как предлагает @ReedCopsey.

Это самый простой синтаксис, который я нашел:

private static void TryCatch( Action action )
{
    TryCatch( () => { action(); return 0; } );
}