C# 方法,无论输入/返回类型如何,都采用另一个方法作为参数

如果标题不清楚,我很抱歉。基本上,我想通过将大量重复的错误处理移到一个地方来干燥我的代码。


我正在调用几种方法,它们都会抛出类似的错误。每个都采用不同的参数,并返回不同的类型。我希望能够做这样的事情:


public class MyClass {

    public static ErrorWrapper<Void> Method1(string s1, string s2) {

        return Wrapper<Void>(System.Method1, s1, s2);

    }


    public static ErrorWrapper<string> Method2(string s) {

        return Wrapper<string>(System.Method2, s);

    }


    public static ErrorWrapper<MyOtherClass> Method3(string s, int i) {

        return Wrapper<MyOtherClass>(System.Method3, s, i)

    }


    private static ErrorWrapper<T> Wrapper<T>(Func f, /*parameters?*/) {

        try {

            return f(parameters);

        } catch {

            // Handle exceptions

        }

}

我需要这样做,因为我正在为一种没有异常处理的语言编写绑定,因此使用错误包装类是安全调用标准库方法的唯一方法。


沧海一幻觉
浏览 96回答 2
2回答

蝴蝶不菲

除非我在这里遗漏了一些东西 -private static ErrorWrapper<T> Wrapper<T>(Func<T> f)&nbsp;{&nbsp; &nbsp; // implementation}用法:return Wrapper<string>(() => System.Method2(s));return Wrapper<MyOtherClass>(() => System.Method3(s, I));

收到一只叮咚

这是我根据我对您正在尝试的事情的理解提出的建议。不幸的是,您必须使用速度DynamicInvoke较慢的 ,以便在调用常规 时在运行时检查类型Delegate。您不能用作void泛型的类型参数,因此我创建了一个MyVoid专门处理的类。我更新了我的答案以反映System.Methods 是实际方法,而不是静态字段,因此它们在传递给时必须进行强制转换Wrapper<>- C# 无法将方法转换为通用Delegate.我还添加了一个类型安全版本,但这需要创建大量样板方法来处理参数数量,但它确实消除了大量转换,并且可以静态调用委托,这应该更高效。我Method3最初不小心采用了两个字符串参数,并且非类型安全版本直到在运行时调用才出现错误。类型安全版本在编译时捕获了错误。public class MyVoid { }public class ErrorWrapper<T> {&nbsp; &nbsp; public T Result;&nbsp; &nbsp; public bool ValidResult;&nbsp; &nbsp; public Exception Exception;&nbsp; &nbsp; public ErrorWrapper(T res) {&nbsp; &nbsp; &nbsp; &nbsp; ValidResult = true;&nbsp; &nbsp; &nbsp; &nbsp; Result = res;&nbsp; &nbsp; }&nbsp; &nbsp; public ErrorWrapper(Exception e) {&nbsp; &nbsp; &nbsp; &nbsp; Exception = e;&nbsp; &nbsp; &nbsp; &nbsp; ValidResult = false;&nbsp; &nbsp; }&nbsp; &nbsp; public ErrorWrapper() { //&nbsp; void&nbsp; &nbsp; &nbsp; &nbsp; ValidResult = true;&nbsp; &nbsp; }}public class MyClass {&nbsp; &nbsp; public static ErrorWrapper<MyVoid> Method1(string s1, string s2) => Wrapper<MyVoid>((Action<string, string>)System.Method1, s1, s2);&nbsp; &nbsp; public static ErrorWrapper<string> Method2(string s) => Wrapper<string>((Func<string, string>)System.Method2, s);&nbsp; &nbsp; public static ErrorWrapper<MyOtherClass> Method3(string s, int i) => Wrapper<MyOtherClass>((Func<string, int, MyOtherClass>)System.Method3, s, i);&nbsp; &nbsp; private static ErrorWrapper<T> Wrapper<T>(Delegate f, params object[] p) {&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switch (default(T)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case MyVoid _:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; f.DynamicInvoke(p);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new ErrorWrapper<T>();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new ErrorWrapper<T>((T)f.DynamicInvoke(p));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; catch (Exception e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Handle exceptions&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new ErrorWrapper<T>(e);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}public static class ErrorWrapper {&nbsp; &nbsp; public static ErrorWrapper<T> New<T>(T res) => new ErrorWrapper<T>(res);}public class MyTypeSafeClass {&nbsp; &nbsp; public static ErrorWrapper<MyVoid> Method1(string s1, string s2) => WrapperAction(System.Method1, s1, s2);&nbsp; &nbsp; public static ErrorWrapper<string> Method2(string s) => WrapperFunc(System.Method2, s);&nbsp; &nbsp; public static ErrorWrapper<MyOtherClass> Method3(string s, int i) => WrapperFunc(System.Method3, s, i);&nbsp; &nbsp; private static ErrorWrapper<MyVoid> WrapperAction<T1, T2>(Action<T1, T2> f, T1 p1, T2 p2) {&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; f(p1, p2);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return ErrorWrapper.New(default(MyVoid));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; catch (Exception e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Handle exceptions&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new ErrorWrapper<MyVoid>(e);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; private static ErrorWrapper<TRes> WrapperFunc<T1, TRes>(Func<T1, TRes> f, T1 p1) {&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return ErrorWrapper.New(f(p1));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; catch (Exception e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Handle exceptions&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new ErrorWrapper<TRes>(e);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; private static ErrorWrapper<TRes> WrapperFunc<T1, T2, TRes>(Func<T1, T2, TRes> f, T1 p1, T2 p2) {&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return ErrorWrapper.New(f(p1, p2));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; catch (Exception e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Handle exceptions&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new ErrorWrapper<TRes>(e);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP