C# 将对泛型方法的引用传递给另一个方法

C# Passing a reference to a generic method to another method

我有一个程序调用了许多具有不同签名的方法,但每个方法内部的异常处理都是相同的。有什么方法可以定义一个方法,该方法可以接受对具有各种签名的泛型方法的引用(这排除了 Delegate - 对吗?)和 return 对象,或 void该方法需要?我正在使用 .NET 4.72。

这是我目前正在做的事情的精简版本和我想做的事情的一些伪代码:

 static class WhosebugQuestion
{
    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
{
}

当然,只需创建一些方法来处理异常,一个用于返回结果,另一个用于 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(...));