简体   繁体   English

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

[英]C# Passing a reference to a generic method to another method

I have a program that calls dozens of methods with varying signatures, but the exception handling inside each one is identical.我有一个程序可以调用数十种具有不同签名的方法,但每个方法内部的异常处理都是相同的。 Is there some way to define a method that can accept a reference to a generic method with various signatures (which rules out a Delegate - right?) and return the object, or void that the method requires?是否有某种方法可以定义一个方法,该方法可以接受对具有各种签名的泛型方法的引用(这排除了Delegate - 对吗?)并返回该方法所需的对象或void I'm using .NET 4.72.我正在使用 .NET 4.72。

Here is stripped down version of what I'm currently doing and some pseudo-code of what I'd like to do:这是我目前正在做的事情的精简版本以及我想做的一些伪代码:

 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
{
}

Sure, just create a few methods whose job it is to handle the exceptions, one for returning results and the other for void, and provide something that does your work.当然,只需创建一些方法来处理异常,一个用于返回结果,另一个用于 void,并提供一些可以完成您的工作的方法。

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

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

    }
}

After that, you can call your other methods with varying signatures inside there.之后,您可以在其中调用具有不同签名的其他方法。

var result = Handle(() => SomeCallWithVaryingSignature(...));
Handle(() => SomeOtherCall(...));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM