将变量ViewModel类型作为泛型传递给方法

本文关键字:方法 泛型 变量 ViewModel 类型 | 更新日期: 2023-09-27 18:13:28

我有一个通用的方法:

public static IRestResponse<T> Get<T>(long id, string apiEndPoint) where T : new()
{
        return Execute<T>(Method.GET, null, string.Concat(apiEndPoint, "/", id));
}

我使用这个方法传递一个视图模型作为通用来获得解析的结果:

var result = RestHelper.Get<AnyViewModel>(1, "Country"));

但是我遇到了一种情况,我有一个变量实体,我从那里获得视图模型:

var entity = "Country"; // This comes as a parameter
var viewModels = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(x => x.FullName.Contains("Core.ViewModel"));
if (viewModels != null)
{
    Type viewModel = viewModels.GetTypes().FirstOrDefault(x => x.Name.Contains(entity));
    if (viewModel != null)
    {
        var result = RestHelper.Get<???>(1, entity);
    }
}

所以我可以用反射获得视图模型类型,但我不知道该传递什么给函数的<???>泛型。

我不知道这对反射的影响有多大,但是我有更多的Get方法过载:

public static IRestResponse Get(string apiEndPoint)
public static IRestResponse<T> Get<T>(string apiEndPoint) where T : new()
public static IRestResponse Get(long id, string apiEndPoint)
public static IRestResponse<T> Get<T>(long id, string apiEndPoint) where T : new()

将变量ViewModel类型作为泛型传递给方法

您必须使用反射来调用具有通用参数的Get<T>方法,使用MakeGenericMethod

Edit由于有多个过载,请使用GetMethods代替并将其缩小到您正在寻找的那个。(我没有看到允许指定类型参数的GetMethod重载。)

MethodInfo method = typeof(RestHelper).GetMethods(BindingFlags.Static | BindingFlags.Public)
    .Where(method => method.Name == "Get" 
        && m.GetGenericArguments().Length == 1
        && m.GetParameters().Length == 2
        // just to be certain, in case someone adds more overloads in the future ...
        && m.GetParameters()[0].ParameterType == typeof(int)
        && m.GetParameters()[1].ParameterType == typeof(string))
    .FirstOrDefault();
if (method == null)
    throw new InvalidOperationException("Couldn't find an overload of RestHelper.Get<T> with int, string parameters");
MethodInfo genericMethod = method.MakeGenericMethod(viewModel);
genericMethod.Invoke(null, new object[] { 1, entity });

编辑

要使用" List<viewModel> ",可以使用Type.MakeGenericType来获得List<T>:

var genericType = typeof(List<>).MakeGenericType(viewModel);
var genericMethod = method.MakeGenericMethod(genericType);