Ошибка при вызове метода расширения с использованием отражения - PullRequest
1 голос
/ 20 сентября 2010

Я получаю исключение 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 Ответ

2 голосов
/ 20 сентября 2010

Проще говоря, вы не уловили результат 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)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...