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
)
精彩评论