C# 通过反射调用泛型方法。发生System.ArgumentException异常
我试图通过反射调用泛型方法。我需要传递实现此方法期望参数的接口的类的对象。我收到System.ArgumentException通知我“ReflectionTest.MyRequest类型的对象”无法转换为“ReflectionTest.IRequest`1[ReflectionTest.MyRequest]”类型C# 通过反射调用泛型方法。发生System.ArgumentException异常,c#,.net,generics,reflection,C#,.net,Generics,Reflection,我试图通过反射调用泛型方法。我需要传递实现此方法期望参数的接口的类的对象。我收到System.ArgumentException通知我“ReflectionTest.MyRequest类型的对象”无法转换为“ReflectionTest.IRequest`1[ReflectionTest.MyRequest]”类型 class Program { static void Main(string[] args) { var request = new MyReque
class Program
{
static void Main(string[] args)
{
var request = new MyRequest();
IMediator mediator = new Mediator();
//This works (of course), but I need to call this by reflection. I don't know the type at design time.
//var r = mediator.Send(request);
//I tried this, but it doesn't work
var type = request.GetType();
var method = mediator.GetType().GetMethod("Send");
var generic = method.MakeGenericMethod(type);
//Exception
var response = generic.Invoke(mediator, new object[] { request });
}
}
public interface IRequest<out TResponse>
{
}
public interface IMediator
{
TResponse Send<TResponse>(IRequest<TResponse> requests);
}
public class MyRequest : IRequest<MyResponse>
{
}
public class MyResponse
{
}
public class Mediator : IMediator
{
public TResponse Send<TResponse>(IRequest<TResponse> requests)
{
Console.WriteLine("Processing...");
return default(TResponse);
}
}
类程序
{
静态void Main(字符串[]参数)
{
var request=new MyRequest();
IMediator mediator=新的mediator();
//这是可行的(当然),但我需要通过反射来调用它。我在设计时不知道它的类型。
//var r=mediator.Send(请求);
//我试过了,但没用
var type=request.GetType();
var method=mediator.GetType().GetMethod(“发送”);
var generic=method.MakeGenericMethod(类型);
//例外情况
var response=generic.Invoke(中介,新对象[]{request});
}
}
公共接口IRequest
{
}
公共接口IMediator
{
t响应发送(IRequest请求);
}
公共类MyRequest:IRequest
{
}
公共类MyResponse
{
}
公共类中介:IMediator
{
公共响应发送(IRequest请求)
{
Console.WriteLine(“处理…”);
返回默认值(t响应);
}
}
有人对我做错了什么有什么建议吗?不幸的是,我不太擅长思考,所以欢迎任何帮助
git回购示例:您为
Send
方法的泛型类型发送了错误的类型。它的泛型类型是响应类型-treresponse
,但您给它的是请求类型-实际上是IRequest
下面将为您提供要调用的正确泛型方法
var generic = method.MakeGenericMethod(typeof(MyReponse));
在这方面:
var generic = method.MakeGenericMethod(type);
您正在创建类型为type
的通用方法,即MyRequest
因此,最终您将使用
MyRequest
作为treresponse
但实际上您想要做的是将MyResponse
作为treresponse
传递
您可以执行以下操作,以便能够动态调用它:
- 获取接口
,它是您的请求正在实现的IMyRequest
- 获取此接口的唯一泛型参数,它将是
treponse
var type = request.GetType();
var responseType = type.GetInterfaces() // [IRequest<MyResponse>]
.Single(i => i.GetGenericTypeDefinition() == typeof(IRequest<>)) // IRequest<MyResponse>
.GetGenericArguments() // [MyResponse]
.Single(); // MyResponse
var method = mediator.GetType().GetMethod("Send");
var generic = method.MakeGenericMethod(responseType); // note that responseType is used here
var response = generic.Invoke(mediator, new object[] { request });
var type=request.GetType();
var responseType=type.GetInterfaces()/[IRequest]
.Single(i=>i.GetGenericTypeDefinition()==typeof(IRequest))//IRequest
.GetGenericArguments()/[MyResponse]
.Single();//我的反应
var method=mediator.GetType().GetMethod(“发送”);
var generic=method.MakeGenericMethod(responseType);//注意这里使用的是responseType
var response=generic.Invoke(中介,新对象[]{request});
毕竟,您确定要将响应绑定到请求的特定定义吗?我不知道您的体系结构以及您试图实现的目标,但是,这可能是一个更灵活的解决方案:
public interface IRequest
{
}
public interface IMediator
{
TResponse Send<TRequest, TResponse>(IRequest request);
}
public class MyRequest : IRequest
{
}
public class MyResponse
{
}
public class Mediator : IMediator
{
public TResponse Send<TRequest, TResponse>(IRequest request)
{
Console.WriteLine("Processing...");
return default(TResponse);
}
}
公共接口IRequest
{
}
公共接口IMediator
{
t响应发送(IRequest请求);
}
公共类MyRequest:IRequest
{
}
公共类MyResponse
{
}
公共类中介:IMediator
{
公共响应发送(IRequest请求)
{
Console.WriteLine(“处理…”);
返回默认值(t响应);
}
}
问题在于,您正在使用MyRequest
而不是MyResponse
创建一个通用方法,请查看签名Send
。尝试:
var generic = method.MakeGenericMethod(typeof(MyReponse));
感谢您的详细解释和代码示例。我现在明白了,我能说什么……我是白痴:)这只是一个较大代码库的小例子。接口IMediator是外部nuget包的一部分。谢谢你的回答!