开发者

Error invoking an extension method using reflection

I am getting an InvalidOperationException with the message:

"Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true."

The following is the relevant part of the code:

// 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 开发者_StackOverflowmethod ElementAt:
MethodInfo elementAtMethod = typeof(Enumerable).GetMethod("ElementAt", BindingFlags.Static | BindingFlags.Public);
elementAtMethod.MakeGenericMethod(entityType);

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

In my last action, the exception mentioned above is thrown. What am I doing wrong? What does this error mean?

I have been investigating and it seems that the method parameter type T is still generic. That's why ContainsGenericParameters is true. How do I set the parameter to the entityType?


Simply , you haven't caught the result of MakeGenericMethod (it returns a different MethodInfo representing the closed method)

elementAtMethod = elementAtMethod.MakeGenericMethod(entityType);

However, might I suggest that in most cases it is easier to use the non-generic IList, falling back to non-generic IEnumerable (reflection and generics are not good friends):

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();

(note, you won't have to use the fallback code, since you are always using List<T> which implements IList)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜