【问题标题】:Invoke ToList() method using reflection at runtime in C#在 C# 运行时使用反射调用 ToList() 方法
【发布时间】:2017-03-16 00:40:00
【问题描述】:

我有一个泛型如下。

public class PaginatedList<T> : List<T>
{...}

我只是想在运行时使用反射在该对象上调用 ToList() 方法。

有人可以帮忙吗。

我才来这么远。

MethodInfo toListMethod = typeof(Enumerable).GetMethod("ToList");
var constructedToList = toListMethod.MakeGenericMethod(TypeObjectOfT);
constructedToList.Invoke(paginatedListObject, null);

I get exception 在最后一行显示消息,Parameter count mismatch。我觉得前两步没问题,因为我检查了toListMethod.ToString()constructedToList.ToString()。他们给了我以下输出,我觉得是正确的。

System.Collections.Generic.List`1[TSource] ToList[TSource](System.Collections.Generic.IEnumerable`1[TSource])
System.Collections.Generic.List`1[AvbhHis.BL.Entities.PatientCategory] ToList[PatientCategory](System.Collections.Generic.IEnumerable`1[AvbhHis.BL.Entities.PatientCategory])

问题: 1. 到目前为止我是对的吗?

  1. MakeGenericMethod() 方法的参数应该是什么。在我的例子中,它是运行时类型 T 对象的实例类型。

  2. Invoke 方法调用似乎有问题。传递 null 作为第二个参数是否正确?第一个参数应该是 PaginatedList 类型的对象吧?

我的精力已经耗尽,请帮忙。

【问题讨论】:

  • @Hani,你有点困惑:Enumerable 是一个包含IEnumerable&lt;T&gt; 扩展方法的类。还有msdn say that Enumerable does have ToList()
  • 混合泛型和反射通常是一种代码味道 - 在您的情况下,有没有办法一般调用 ToList
  • @Grundy 你很困惑 - OP 正在通过反射在 Enumerable 上调用 ToList
  • @DStanley,是的 :-) 可能我不太理解之前的评论 Hani :-)
  • 重点是 ToList 不是扩展方法,而是 IEnumerable 上的方法。它是扩展类上的静态方法,以 IENumerable 作为其第一个参数

标签: c# generics reflection


【解决方案1】:

第一个参数 [to Invoke] 应该是 PaginatedList 类型的对象吧?

ToListEnumerable 上的静态方法,它采用IEnumerable&lt;T&gt; 作为唯一参数:

public static List<TSource> ToList<TSource>(
    this IEnumerable<TSource> source
)

Invokeinstance 作为第一个参数,然后是 method parameters。对于静态方法,您使用 null 作为“实例”参数。

所以正确的语法应该是

object o = constructedToList.Invoke(null, new object[] {paginatedListObject});

o 将成为List&lt;T&gt; 类型的对象(但你不知道T 在编译时是什么,所以你不能转换它)。

【讨论】:

  • 我现在在调用过程中得到了这个异常。 "'System.Reflection.MethodBase.Invoke(object, object[])' 的最佳重载方法匹配有一些无效参数"
  • @DumbDev 现在试试 - 我忘了Invoke 不使用params 所以第二个参数必须作为数组传递。
  • 谢谢斯坦利。它现在完美地工作。由于我只能选择一个,所以我会选择你的而不做太多判断。
【解决方案2】:

List 有一个构造函数,它接受一个 IEnumerable(在 ToList 中被调用),因此您可以通过编写以下代码来简化此任务:

    var resul = Activator.CreateInstance(typeof(List<>).MakeGenericType(TypeObjectOfT), paginatedListObject);

【讨论】:

  • 这也是一个可爱的答案。
  • 使泛型类型将数组作为第一个参数。 .MakeGenericType(new Type[] { TypeObjectOfT })
  • @BojidarStanchev 正确,但它具有 params 关键字,因此您不需要删除数组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-02
相关资源
最近更新 更多