C# 在c中使用泛型和Func避免代码重复的最佳方法#
我想知道使用泛型Func或任何其他方法避免重复某些代码结构的最佳方法是什么。 作为一个实际的例子,我需要调用20个不同的WCF方法,但我希望有更多的代码来处理异常 假设这是wcf代理C# 在c中使用泛型和Func避免代码重复的最佳方法#,c#,generics,func,code-duplication,C#,Generics,Func,Code Duplication,我想知道使用泛型Func或任何其他方法避免重复某些代码结构的最佳方法是什么。 作为一个实际的例子,我需要调用20个不同的WCF方法,但我希望有更多的代码来处理异常 假设这是wcf代理 class ClassWithMethodsToCall // say wcf proxy { public Out1 GetOut1(In1 inParam) { return null; } // would have some spesific implementation
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;
}
}
}
类CallerHelpWithCommonExceptionHandler
{
公共Tout调用(Tin参数,Func wcfMethodToCall)
{
尝试
{
返回wcfMethodToCall(参数);
}
捕获(例外情况除外)
{
//做什么
投掷;
}
}
}
我用它:
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
var callerHelper=new callerHelpWithCommonExceptionHandler();
var theFunctionsToCall=newclasswithmethodstocall();
var in1=新in1();//视情况而定
var ou1=callerHelper.Call(in1,functionstocall.GetOut1);
var in2=新in2();//视情况而定
var ou2=callerHelper.Call(in2,functionstocall.GetOut2);
//等等
有更好更优雅的方式吗?面向对象方式的替代方案,模板设计模式
谢谢,al看起来您正在向类中添加代码来实现一个类(例如,记录异常),因此您可能需要使用 例如:
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;
}
}
}
class Out1{};//一些特定的数据结构
类{}//某些特定的数据结构
类Out2{}//某些特定的数据结构
类In2{}//某些特定的数据结构
类Out3{}//某些特定的数据结构
类In3{}
内部接口IClassWithMethodsToCall
{
Out1 GetOut1(In1 inParam);
Out2 GetOut2(In2 inParam);
Out3 GetOut3(In3 inParam);
}
类ClassWithMethodsToCallImpl:IClassWithMethodsToCall
{
public Out1 GetOut1(In1 inParam){return null;}//将有一些特殊的实现
public Out2 GetOut2(In2 inParam){return null;}
public Out3 GetOut3(In3 inParam){return null;}
}
类ClassWithMethodsToCall:IClassWithMethodsToCall
{
方法为CallImpl的私有只读类;
公共类WithMethodsToCall(类WithMethodsToCallImpl)
{
_impl=impl;
}
公共输出1输出1(输入1参数)
{
返回tryFunc(()=>_impl.GetOut1(inParam));
}
公共出口2出口2(In2输入参数)
{
返回tryFunc(()=>_impl.GetOut2(inParam));
}
公共出口3出口3(In3 inParam)
{
返回tryFunc(()=>_impl.GetOut3(inParam));
}
专用静态T tryFunc(Func Func)
{
尝试
{
返回func();
}
捕获(异常)
{
//例外地做某事
投掷;
}
}
}
客户端代码只会使用IClassWithMethodsToCall
,您可能会在某个地方使用工厂方法创建ClassWithMethodsToCallImpl
,并使用它创建ClassWithMethodsToCall
,并将ClassWithMethodsToCall
作为IClassWithMethodsToCall
返回
或者(可能更好)使用。这需要更多的投资,可能还需要使用第三方库来支持,但从长远来看,这可能是一条路
我注意到您正在使用WCF代理。因为它使用MarshalByRefObject,所以您可以利用它来实现AOP 这根本不是重复。你的class
ClassWithMethodsToCall
看起来很适合我。您的CallerHealthCommonExceptionHandler
使情况变得更糟。同意,看起来更糟。您正在寻找的可能是面向方面的编程短AOP这里是一个示例,没有CallerHealthCommonExceptionHandler,我必须对ClassWithMethodsToCall的每个metod调用重复try-catch。如果我有20个方法,我会为每个方法重复相同的错误处理代码块。而据我所知,AOP更具体于异常、日志记录等常见操作。我正在寻找适合任何常见代码块的东西,例如“1.解决方案:”似乎与我的类似您认为如何?@user241829是的,这与我展示的private static T tryFunc(Func Func)
基本相同-您可以使用这种方法通过将重试放入tryFunc()中来实现重试逻辑
@user241829 AOP不仅限于日志记录/异常处理,还可以实现缓存、事务处理等功能。拦截对objects方法的调用所需的一切。因此,在AOP中也可以使用重试逻辑