C# 如何按名称及其泛型参数获取泛型方法的MethodInfo?
我有这个界面:C# 如何按名称及其泛型参数获取泛型方法的MethodInfo?,c#,reflection,system.reflection,C#,Reflection,System.reflection,我有这个界面: interface IRepository { string GetId<T>(T obj) where T : IDomainObject; string GetId<T>(Reference<T> reference) where T : IDomainObject; } 我的问题是:如何获取接受引用的I假定中的GetId方法的属性? 以下是我尝试过的: public MethodInfo GetReferenceAcc
interface IRepository
{
string GetId<T>(T obj) where T : IDomainObject;
string GetId<T>(Reference<T> reference) where T : IDomainObject;
}
我的问题是:如何获取接受引用的I假定中的GetId
方法的属性?
以下是我尝试过的:
public MethodInfo GetReferenceAcceptingGetIdMethod()
{
// We want to return the MethodInfo for the GetId<T> method of IRepository
// that accepts a Reference<T> argument.
var repositoryInterfaceType = typeof(IRepository);
// Look through all methods of IRepository...
foreach (var m in repositoryInterfaceType.GetMethods())
{
// ... to find a candidate method, going by Genericness and Name ...
if (m.IsGenericMethodDefinition && m.Name == nameof(IRepository.GetId))
{
// ... and to narrow it further down by looking at the parameters ...
var parameters = m.GetParameters();
if (parameters.Length == 1)
{
// ... to check if the one and only parameter is a generic Reference<>.
var firstParamType = parameters[0].ParameterType;
var genericReferenceType = typeof(Reference<>);
if (firstParamType == genericReferenceType)
{
// !!! This if will never be true.
// Why?
// And what do I have to change the condition into to make it work?
return m;
}
}
}
}
throw new Exception();
}
公共方法信息GetReferenceAcceptingGetIdMethod()
{
//我们想返回IRepository的GetId方法的MethodInfo
//接受引用参数的。
var repositoryInterfaceType=类型(IRepository);
//通读所有的信息存储方法。。。
foreach(repositoryInterfaceType.GetMethods()中的var m)
{
//…要查找候选方法,请按泛型和名称。。。
if(m.IsGenericMethodDefinition&&m.Name==nameof(IRepository.GetId))
{
//…并通过查看参数进一步缩小范围。。。
var参数=m.GetParameters();
if(parameters.Length==1)
{
//…以检查唯一的参数是否为泛型引用。
var firstParamType=参数[0]。ParameterType;
var generireferencetype=typeof(参考);
if(firstParamType==genericReferenceType)
{
//!!!这永远不会是真的。
//为什么??
//我必须把条件变成什么才能让它工作?
返回m;
}
}
}
}
抛出新异常();
}
该方法的参数类型似乎与完全开放的泛型类型有所不同。我猜,方法参数的类型似乎以某种方式与方法的泛型类型参数相关联
那么,在这种情况下,如何获取
MethodInfo
?参数类型不能是泛型类型定义。它有一个类型参数-这是该方法的类型参数。您可以从MethodInfo.GetGenericArguments()
中获取该类型参数,然后将其与typeof(Reference)一起使用。MakeGenericType(…)
以获取所需的参数类型
下面是一个完整的示例,基本上是修改原始代码:
using System;
using System.Reflection;
class Reference<T> {}
interface IDomainObject {}
interface IRepository
{
string GetId<T>(T obj) where T : IDomainObject;
string GetId<T>(Reference<T> reference) where T : IDomainObject;
}
class Test
{
static void Main()
{
var method = GetReferenceAcceptingGetIdMethod();
Console.WriteLine(method);
}
public static MethodInfo GetReferenceAcceptingGetIdMethod()
{
var repositoryInterfaceType = typeof(IRepository);
foreach (var m in repositoryInterfaceType.GetMethods())
{
if (m.IsGenericMethodDefinition && m.Name == nameof(IRepository.GetId))
{
var typeParameter = m.GetGenericArguments()[0];
var expectedParameterType = typeof(Reference<>).MakeGenericType(typeParameter);
var parameters = m.GetParameters();
if (parameters.Length == 1)
{
var firstParamType = parameters[0].ParameterType;
if (firstParamType == expectedParameterType)
{
return m;
}
}
}
}
throw new Exception();
}
}
使用系统;
运用系统反思;
类引用{}
接口IDomainObject{}
界面假定
{
字符串GetId(T obj),其中T:IDomainObject;
字符串GetId(引用),其中T:IDomainObject;
}
课堂测试
{
静态void Main()
{
var method=GetReferenceAcceptingGetIdMethod();
控制台写入线(方法);
}
公共静态方法信息GetReferenceAcceptingGetIdMethod()
{
var repositoryInterfaceType=类型(IRepository);
foreach(repositoryInterfaceType.GetMethods()中的var m)
{
if(m.IsGenericMethodDefinition&&m.Name==nameof(IRepository.GetId))
{
var typeParameter=m.GetGenericArguments()[0];
var expectedParameterType=typeof(参考)。MakeGenericType(typeParameter);
var参数=m.GetParameters();
if(parameters.Length==1)
{
var firstParamType=参数[0]。ParameterType;
if(firstParamType==expectedParameterType)
{
返回m;
}
}
}
}
抛出新异常();
}
}
哇,太酷了。我没想到m
在它仍然打开时会有一个泛型参数。此外,泛型参数似乎是一种非常奇怪的“类型”,名为T
。但是您的解决方案非常有效,所以非常感谢。@HaukeP:在将其包含到代码中之前,请后退一步以确保您理解它是值得的(这样您以后可以在必要时对其进行更改,或者在将来编写类似的代码)。它一点也不奇怪——它是方法的类型参数。看看您是如何声明参数的:Reference
。这不是一个开放的泛型类型;它是一个泛型类型,使用的类型参数恰好是方法中的类型参数。
using System;
using System.Reflection;
class Reference<T> {}
interface IDomainObject {}
interface IRepository
{
string GetId<T>(T obj) where T : IDomainObject;
string GetId<T>(Reference<T> reference) where T : IDomainObject;
}
class Test
{
static void Main()
{
var method = GetReferenceAcceptingGetIdMethod();
Console.WriteLine(method);
}
public static MethodInfo GetReferenceAcceptingGetIdMethod()
{
var repositoryInterfaceType = typeof(IRepository);
foreach (var m in repositoryInterfaceType.GetMethods())
{
if (m.IsGenericMethodDefinition && m.Name == nameof(IRepository.GetId))
{
var typeParameter = m.GetGenericArguments()[0];
var expectedParameterType = typeof(Reference<>).MakeGenericType(typeParameter);
var parameters = m.GetParameters();
if (parameters.Length == 1)
{
var firstParamType = parameters[0].ParameterType;
if (firstParamType == expectedParameterType)
{
return m;
}
}
}
}
throw new Exception();
}
}