c# - 在 C# 中使用泛型和 Func 避免代码重复的最佳方法

标签 c# generics func code-duplication

我想知道通过使用 Generics Func 或任何其他方式避免重复某些重复代码结构的最佳方法是什么。 作为一个实际示例,我需要调用 20 种不同的 WCF 方法,但我希望有代码来处理异常。

假设这是 wcf 代理

 class ClassWithMethodsToCall // say wcf proxy
    {
        public Out1 GetOut1(In1 inParam) { return null; } // would have some spesific implementation 
        public Out2 GetOut2(In2 inParam) { return null; }
        public Out3 GetOut3(In3 inParam) { return null; }
    }

class Out1 { }  // some specific data structure
class In1 { }   // some specific data structure

class Out2 { }  // some specific data structure
class In2 { }   // some specific data structure

class Out3 { }  // some specific data structure
class In3 { }   // some specific data structure

我创建了以下内容以进行单一错误处理

class CallerHelperWithCommonExceptionHandler
    {
        public Tout Call<Tout, Tin>(Tin parameters, Func<Tin,Tout> wcfMethodToCall)
        {
            try
            {
                return wcfMethodToCall(parameters);
            }
            catch (Exception ex)
            {
                // do what ever
                throw;
            }
        }
    }

我用它:

var callerHelper = new CallerHelperWithCommonExceptionHandler();
            var theFunctionsToCall = new ClassWithMethodsToCall();

        var in1 = new In1(); // init as appropriate
        var ou1 = callerHelper.Call<Out1, In1>(in1, theFunctionsToCall.GetOut1);

        var in2 = new In2(); // init as appropriate
        var ou2 = callerHelper.Call<Out2, In2>(in2, theFunctionsToCall.GetOut2);

        // and so on

有没有更好更优雅的方式?面向对象方式的替代方案,模板设计模式?

谢谢你

最佳答案

看起来您正在添加代码来实现 cross-cutting concern到一个类(例如记录异常),所以你可能想使用 decorator pattern .

例如:

class Out1 { };  // some specific data structure
class In1 { }   // some specific data structure

class Out2 { }  // some specific data structure
class In2 { }   // some specific data structure

class Out3 { }  // some specific data structure
class In3 { }

internal interface IClassWithMethodsToCall
{
    Out1 GetOut1(In1 inParam);
    Out2 GetOut2(In2 inParam);
    Out3 GetOut3(In3 inParam);
}

class ClassWithMethodsToCallImpl: IClassWithMethodsToCall
{
    public Out1 GetOut1(In1 inParam) { return null; } // would have some spesific implementation 
    public Out2 GetOut2(In2 inParam) { return null; }
    public Out3 GetOut3(In3 inParam) { return null; }
}

class ClassWithMethodsToCall: IClassWithMethodsToCall
{
    private readonly ClassWithMethodsToCallImpl _impl;

    public ClassWithMethodsToCall(ClassWithMethodsToCallImpl impl)
    {
        _impl = impl;
    }

    public Out1 GetOut1(In1 inParam)
    {
        return tryFunc(() => _impl.GetOut1(inParam));
    }

    public Out2 GetOut2(In2 inParam)
    {
        return tryFunc(() => _impl.GetOut2(inParam));
    }

    public Out3 GetOut3(In3 inParam)
    {
        return tryFunc(() => _impl.GetOut3(inParam));
    }

    private static T tryFunc<T>(Func<T> func)
    {
        try
        {
            return func();
        }

        catch (Exception exception)
        {
            // Do something with exception
            throw;
        }
    }
}

客户端代码只会使用 IClassWithMethodsToCall,您可能会在某处使用工厂方法来创建 ClassWithMethodsToCallImpl 并使用它来创建 ClassWithMethodsToCall 并将 ClassWithMethodsToCall 作为 IClassWithMethodsToCall 返回。

或者(可能更好)是使用 Aspect-oriented programming .这需要更多投资,并且可能需要使用第三方库来支持它,但从长远来看,这可能是可行的方法。

我注意到您正在使用 WCF 代理。因为它使用 MarshalByRefObject,所以您可以利用它来实现 AOP。 There's some information about it in a blog here .

关于c# - 在 C# 中使用泛型和 Func 避免代码重复的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28602807/

相关文章:

c# - P/Invoke、Pinning 和 KeepAlive 最佳实践

java - 将方法转换为具有多种数据类型的泛型

c# - 如何使用反射在 IEnumerable<T> 上调用 System.Linq.Enumerable.Count<>?

c# - 请求消息已发送。不能多次发送同一个请求报文

c# - 为 C# 中的 Func<Type1, Type2> 序列提供简称

c# - 无法将类型 'Task<Derived>' 转换为 'Task<Interface>'

c# - 关于经典 MVC 的问题

c# - 等待BackgroundWorker RunWorkerCompleted

java - Guice - 以编程方式创建的绑定(bind)

c# - 如何评估作为参数传递给方法的 Func/Delegate/Expression?