[英]How to get MethodInfo for a generic method by name and its generic parameters?
我有這個界面:
interface IRepository
{
string GetId<T>(T obj) where T : IDomainObject;
string GetId<T>(Reference<T> reference) where T : IDomainObject;
}
確切的IDomainObject
和Reference
與該問題無關。 因此,假設它們完全為空:
interface IDomainObject
{
// something
}
class Reference<T> where T : IDomainObject
{
// something
}
我的問題是: 如何在接受Reference<T>
IRepository
中獲取GetId<T>
方法的MethodInfo
?
這是我嘗試過的:
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();
}
看來方法的參數類型與完全開放的泛型類型有所不同。 我猜,似乎方法的參數類型以某種方式鏈接到方法的泛型類型參數。
那么在這種情況下如何獲取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();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.