C# 如何在强类型接口上引用方法名
很抱歉,如果这个问题已经得到了回答,但我认为我实际上缺乏正式的教育来正确地提出这个问题,因此也缺乏正确的标准来成功地寻找它 我有一个API,它有几个调用,它们做几乎相同的事情,但使用不同的方法对不同的输入对象进行操作,但总是形成相同的接口。我想将剪切粘贴方面从API方法调用过程中去掉,以便在所有方法调用中完成相同的公共代码。我已经设法为输入和输出对象使用泛型获得了一个有效的解决方案,并且正在引用要从字符串调用的方法名。我希望对方法的引用是强类型的,而不是基于字符串的,这样在重新分解时重命名方法名就不会让方法名的“神奇”字符串在运行时等待爆炸 下面是我试图实现的一个非常简化的版本C# 如何在强类型接口上引用方法名,c#,reflection,interface,strongly-typed-view,strong-typing,C#,Reflection,Interface,Strongly Typed View,Strong Typing,很抱歉,如果这个问题已经得到了回答,但我认为我实际上缺乏正式的教育来正确地提出这个问题,因此也缺乏正确的标准来成功地寻找它 我有一个API,它有几个调用,它们做几乎相同的事情,但使用不同的方法对不同的输入对象进行操作,但总是形成相同的接口。我想将剪切粘贴方面从API方法调用过程中去掉,以便在所有方法调用中完成相同的公共代码。我已经设法为输入和输出对象使用泛型获得了一个有效的解决方案,并且正在引用要从字符串调用的方法名。我希望对方法的引用是强类型的,而不是基于字符串的,这样在重新分解时重命名方法名
class ARequest { };
class AResponse { };
class BRequest { };
class BResponse { };
interface IWorker
{
AResponse DoA(ARequest aRequest);
BResponse DoB(BRequest bRequest);
}
class Worker : IWorker
{
public AResponse DoA(ARequest aRequest)
{
return new AResponse();
}
public BResponse DoB(BRequest bRequest)
{
return new BResponse();
}
}
class Program
{
static void Main(string[] args)
{
// current concrete copy & paste implementation
var a1 = API.DoA(new ARequest { });
var b1 = API.DoB(new BRequest { });
// new generic implementation
var a2 = API.DoA2(new ARequest { });
var b2 = API.DoB2(new BRequest { });
}
}
static class API
{
// current concrete copy & paste implementation
public static AResponse DoA(ARequest aRequest)
{
// lots of common code for logging & preperation
var worker = GetWorker();
return worker.DoA(aRequest);
}
public static BResponse DoB(BRequest bRequest)
{
// lots of common code for logging & preperation
var worker = GetWorker();
return worker.DoB(bRequest);
}
private static IWorker GetWorker()
{
return new Worker();
}
// new generic implementation Attempt
public static AResponse DoA2(ARequest aRequest)
{
return DoGen<ARequest, AResponse>(aRequest, "DoA"); // how to make references to DoA and DoB methods on the IWorker strongly typed?
}
public static BResponse DoB2(BRequest bRequest)
{
return DoGen<BRequest, BResponse>(bRequest, "DoB"); // how to make references to DoA and DoB methods on the IWorker strongly typed?
}
public static TResponse DoGen<TRequest, TResponse>(TRequest requestObj, string methodname)
where TRequest : class
where TResponse : class
{
// lots of common code for logging & preperation
var worker = GetWorker();
var mi = worker.GetType().GetMethod(methodname);
var result = mi.Invoke(worker, new Object[] { requestObj });
return result as TResponse;
}
}
class-ARequest{};
类AResponse{};
类BRequest{};
类b响应{};
接口IWorker
{
AResponse-DoA(ARequest-ARequest);
Bressponse-DoB(BRequest-BRequest);
}
班主任:IWorker
{
公共AresResponse DoA(ARequest ARequest)
{
返回新的AResponse();
}
公共响应DoB(BRequest-BRequest)
{
返回新的b响应();
}
}
班级计划
{
静态void Main(字符串[]参数)
{
//当前的具体复制和粘贴实现
var a1=API.DoA(新的ARequest{});
var b1=API.DoB(新BRequest{});
//新的通用实现
var a2=API.DoA2(新的ARequest{});
var b2=API.DoB2(新BRequest{});
}
}
静态类API
{
//当前的具体复制和粘贴实现
公共静态AresResponse DoA(ARequest ARequest)
{
//许多用于日志记录和准备操作的通用代码
var-worker=GetWorker();
返回工人.DoA(aRequest);
}
公共静态响应DoB(BRequest-BRequest)
{
//许多用于日志记录和准备操作的通用代码
var-worker=GetWorker();
返回工人。DoB(布雷奎斯特);
}
私有静态IWorker GetWorker()
{
返回新工人();
}
//新的通用实现尝试
公共静态AresResponse DoA2(ARequest ARequest)
{
return DoGen(aRequest,“DoA”);//如何在IWorker强类型上引用DoA和DoB方法?
}
公共静态响应DoB2(BRequest-BRequest)
{
return DoGen(bRequest,“DoB”);//如何在IWorker强类型上引用DoA和DoB方法?
}
公共静态响应DoGen(TRequest requestObj,string methodname)
特雷奎斯特:课堂在哪里
在哪里响应:类
{
//许多用于日志记录和准备操作的通用代码
var-worker=GetWorker();
var mi=worker.GetType().GetMethod(methodname);
var result=mi.Invoke(worker,新对象[]{requestObj});
返回结果作为响应;
}
}
Func var a1 = new Func<ARequest, AResponse>(API.DoA);
var b1 = new Func<BRequest, BResponse>(API.DoB);
var a2 = new Func<ARequest, AResponse>(API.DoA2);
var b2 = new Func<BRequest, BResponse>(API.DoB2);
a1.Invoke(new ARequest { });
b1.Invoke(new BRequest { });
a2.Invoke(new ARequest { });
b2.Invoke(new ARequest { }); // fails at compile time
var a1=新函数(API.DoA);
变量b1=新函数(API.DoB);
var a2=新函数(API.DoA2);
变量b2=新函数(API.DoB2);
a1.调用(新请求{});
b1.调用(新的BRequest{});
a2.调用(新请求{});
b2.调用(新的ARequest{});//在编译时失败
为方法添加一名代表:
public delegate TResponse DoXDelegate<in TRequest, out TResponse>(TRequest request);
public static TResponse DoGen<TRequest, TResponse>(TRequest requestObj, DoXDelegate<TRequest, TResponse> method)
where TRequest : class
where TResponse : class
{
// lots of common code for logging & preperation
var worker = GetWorker();
/*var mi = worker.GetType().GetMethod(methodname);
var result = mi.Invoke(worker, new Object[] { requestObj });
return result as TResponse;*/
return method.Invoke(requestObj);
}
public委托响应DoXDelegate(TRequest请求);
公共静态响应DoGen(TRequest-requestObj,DoXDelegate方法)
特雷奎斯特:课堂在哪里
在哪里响应:类
{
//许多用于日志记录和准备操作的通用代码
var-worker=GetWorker();
/*var mi=worker.GetType().GetMethod(methodname);
var result=mi.Invoke(worker,新对象[]{requestObj});
返回结果作为响应*/
返回方法.Invoke(requestObj);
}
像这样使用Func
:
编辑:该解决方案示例仅在工作者对象来自何处无关紧要的情况下可用
// new generic implementation Attempt
public static AResponse DoA2(ARequest aRequest)
{
return DoGen<ARequest, AResponse>(aRequest, DoA); // how to make refreces to DoA and DoB methods strongly typed?
}
public static BResponse DoB2(BRequest bRequest)
{
return DoGen<BRequest, BResponse>(bRequest, DoB); // how to make refreces to DoA and DoB methods strongly typed?
}
public static TResponse DoGen<TRequest, TResponse>(TRequest requestObj, Func<TRequest, TResponse> func)
where TRequest : class
where TResponse : class
{
// lots of common code for logging & preperation
var result = func(requestObj);
return result as TResponse;
}
//新的通用实现尝试
公共静态AresResponse DoA2(ARequest ARequest)
{
return DoGen(aRequest,DoA);//如何使DoA和DoB方法的引用强类型化?
}
公共静态响应DoB2(BRequest-BRequest)
{
return DoGen(bRequest,DoB);//如何使DoA和DoB方法的引用强类型化?
}
公共静态响应DoGen(TRequest requestObj,Func Func)
特雷奎斯特:课堂在哪里
在哪里响应:类
{
//许多用于日志记录和准备操作的通用代码
var结果=func(requestObj);
返回结果作为响应;
}
方法名称的“魔法”字符串更改为委托上的委托
public static AResponse DoA2(ARequest aRequest)
{
return DoGen<ARequest, AResponse>(aRequest, worker => worker.DoA);
}
public static BResponse DoB2(BRequest bRequest)
{
return DoGen<BRequest, BResponse>(bRequest, worker => worker.DoB);
}
public static TResponse DoGen<TRequest, TResponse>(TRequest requestObj,
Func<IWorker, Func<TRequest, TResponse>> methodRef)
where TRequest : class
where TResponse : class
{
// lots of common code for logging & preparation
var worker = GetWorker();
var method = methodRef(worker);
return method(requestObj);
}
公共静态AresResponse DoA2(ARequest ARequest)
{
返回DoGen(aRequest,worker=>worker.DoA);
}
公共静态响应DoB2(BRequest-BRequest)
{
返回DoGen(bRequest,worker=>worker.DoB);
}
公共静态响应DoGen(TRequest requestObj,
Func methodRef)
特雷奎斯特:课堂在哪里
在哪里响应:类
{
//许多用于记录和准备的通用代码
var-worker=GetWorker();
var方法=methodRef(工人);
返回方法(requestObj);
}
响应类型是否以任何方式相关?看看这篇博文,它描述了一个满足您需要的模型:Foo42:在最终实现中,它们有一些来自公共基类的公共字段。在这个例子中,它们是没有关联的,也就是说(据我所知),它们正是我想要的。现在我只需要知道它在做什么。我想是时候停止回避函子了。那不是使用API的DoA和DoB方法,而不是worker对象上的方法吗?理想的效果是调用这些方法