C# Передача ссылки на обобщенный метод c другому методу - PullRequest
0 голосов
/ 29 февраля 2020

У меня есть программа, которая вызывает десятки методов с различными сигнатурами, но обработка исключений внутри каждого идентична. Есть ли какой-нибудь способ определить метод, который может принять ссылку на обобщенный метод c с различными сигнатурами (что исключает Delegate - верно?) И вернуть объект, или void, который требуется методу? Я использую. NET 4.72.

Вот урезанная версия того, что я сейчас делаю, и некоторый псевдокод того, что я хотел бы сделать:

 static class StackOverflowQuestion
{
    public static void Main(string[] args)
    {
        // What I'm currently doing:
        MethodOne("x");
        int ret = MethodTwo(0);
        //.
        //.
        //.
        MethodNineteen();

        // what I'd like to do is replace MethodOne(), MethodTwo(), ..., Method Nineteen()
        // with something like:
        RunMethod<void>(MethodOneWork, new object[] {"x"});
        ret = RunMethod<int>(MethodTwoWork, new object []{1});
        //.
        //.
        //.
        RunMethod<void>(MethodNineteenWork, null);          
    }

    private static void MethodOne(string st)
    {
        try
        {
            // the try clause is the only difference between the methods
            MethodOneWork(st);
        }
        catch (MyExceptionA)
        {
            HandleExceptionA();
            return;
        }
        catch(MyExceptionB)
        {
            HandleExceptionB();
        }
        catch(Exception)
        {
            HandleGenericException();
        }
    }

    private static int MethodTwo(int v)
    {
        try
        {
            return MethodTwoWork(v);
        }
        catch (MyExceptionA)
        {
            HandleExceptionA();
            return -1;
        }
        catch (MyExceptionB)
        {
            HandleExceptionB();
            return -2;
        }
        catch(Exception)
        {
            HandleGenericException();
            return 0;
        }          
    }

    private static void MethodNineteen()
    {
        try
        {
            MethodNineteenWork();
        }
        catch (MyExceptionA)
        {
            HandleExceptionA();
            return;
        }
        catch (MyExceptionB)
        {
            HandleExceptionB();
        }
        catch(Exception)
        {
            HandleGenericException();
        }
    }

    /// <summary>
    /// Run generic method with generic signature
    /// </summary>
    private static <T> RunMethod(Delegate MethodxWork, object[] myParams)
    {
        try
        {
            new <T>() retVal = MethodxWork(myParams);
            return retVal;
         }
        catch (MyExceptionA)
        {
            HandleExceptionA();
            return new <T>();
        }
        catch (MyExceptionB)
        {
            HandleExceptionB();
            return new <T>();
        }
        catch(Exception)
        {
            HandleGenericException();
            return new <T>();
        }
    }

    private static void HandleExceptionB()
    {
         //handle it
    }

    private static void HandleExceptionA()
    {
         //handle it
    }

    private static void HandleGenericException()
    {
        //handle it
    }


}

internal  class MyExceptionB : Exception
{
}

internal class MyExceptionA : Exception
{
}

1 Ответ

3 голосов
/ 29 февраля 2020

Конечно, просто создайте несколько методов, чья работа заключается в обработке исключений, один для возврата результатов, а другой для void, и предоставьте что-то, что сделает вашу работу.

T Handle<T>(Func<T> call)
{
    try
    {
        return call();
    }
    catch(YourException ex)
    {
        return default;
    }
}

void Handle(Action call)
{
    try
    {
        call();
    }
    catch(YourException ex)
    {

    }
}

После этого вы можете вызывать другие методы с разными сигнатурами внутри.

var result = Handle(() => SomeCallWithVaryingSignature(...));
Handle(() => SomeOtherCall(...));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...