使用反射调用扩展方法时出错

时间:2010-09-20 10:11:46

标签: c# reflection

我收到一条带有消息的InvalidOperationException:

“无法对ContainsGenericParameters为true的类型或方法执行后期绑定操作。”

以下是代码的相关部分:

// Gets the entity type of the table to update.
Type entityType = Jobs.GetType(syncSettings.TableToUpdate);

// Creates a generic list with the same type to hold the records to update.
Type listType = typeof(List<>).MakeGenericType(entityType);
object recordsToUpdate = Activator.CreateInstance(listType);

// Fills the list recordsToUpdate...
// A few lines below, I try to call the extension method ElementAt:
MethodInfo elementAtMethod = typeof(Enumerable).GetMethod("ElementAt", BindingFlags.Static | BindingFlags.Public);
elementAtMethod.MakeGenericMethod(entityType);

object record = elementAtMethod.Invoke(
                                     recordsToUpdate,
                                     new object[] { recordsToUpdate, recordIndex });

在我的上一个操作中,抛出了上面提到的异常。我究竟做错了什么?这个错误意味着什么?

我一直在研究,似乎方法参数类型T仍然是通用的。这就是ContainsGenericParameters为真的原因。如何将参数设置为entityType?

1 个答案:

答案 0 :(得分:2)

简单地说,您没有抓住MakeGenericMethod的结果(它返回不同的 MethodInfo代表已关闭的方法)

elementAtMethod = elementAtMethod.MakeGenericMethod(entityType);

但是,我可以建议在大多数情况下使用非通用IList更容易,回归非通用IEnumerable(反射和泛型不是好朋友):

IList list = recordsToUpdate as IList;
if(list != null) return list[recordIndex];
// fallback to IEnumerable
if(recordIndex < 0) throw new IndexOutOfRangeException();
IEnumerable enumerable = (IEnumerable)recordsToUpdate;
foreach (object item in enumerable) {
    if (recordIndex-- == 0) return item;
}
throw new IndexOutOfRangeException();

(请注意,您不必使用后备代码,因为您始终使用List<T>来实现IList