Bezdepbonusu7Программирование: статьи и ответы

Вопрос

С# отражение с динамическим классом

Автор вопроса: Tiago SchäfferОтветов: 3

Мне нужно выполнить метод "FindAll" на моей странице. Этот метод возвращает список объектов.

Это мой метод, который я выполняю "FindAll". FindAll требует int и возвращает список этих классов.

public void ObjectSource(int inicio, object o)
{
  Type tipo = o.GetType();
  object MyObj = Activator.CreateInstance(tipo);
  object[] args = new object[1];
  args[0] = inicio;
  List<object> list = new List<object>();
  object method = tipo.InvokeMember("FindAll", BindingFlags.Default | BindingFlags.InvokeMethod, null, null, args);
}

Когда я запускаю ObjectSource, он возвращает ok, но я не могу получить доступ к результату. В VS2008 я могу визуализировать список с помощью "ctrl + Alt + q", но приведение не работает.

Забыл сказать: этот метод "НайтиВсе" статичен!

  • Почему вы создаете новый экземпляр типа, почему вы создаете List<object> и не используете его, и почему вы фактически игнорируете возвращаемое значение метода? Jon Skeet 13.11.2009
  • И: зачем создавать общий список‹T› и вставлять в него объект? Wim Hollebrandse 13.11.2009
  • Почему вы создаете новый экземпляр типа? Не используется, удаляю. почему вы создаете объект списка и не используете его? только для теста. Метод FindAll возвращает IEnumerable, но я использую гентерикс, как опубликовал Вим Холлебрандсе. почему вы фактически игнорируете возвращаемое значение метода? мне нужен результат этого метода, и я не знаю, как его получить! Tiago Schäffer 13.11.2009
  • Возвращаемое значение хранится в вашей локальной переменной, которую вы неправильно назвали методом, а не в чем-то вроде returnObject. Wim Hollebrandse 13.11.2009

reflection

Ответы

Ответ 1 · рейтинг 1 · Wim Hollebrandse

Здесь происходит несколько вещей, во-первых, ваш метод не возвращает результат.

Во-вторых, когда вы возвращаете объект, ничто не мешает вам выполнить приведение к соответствующему типу в вызывающем коде.

В-третьих, вы можете использовать Generics, чтобы сделать этот метод строго типизированным:

public T ObjectSource<T>(int inicio, T o)
{
  Type tipo = typeof(T);
  object MyObj = Activator.CreateInstance(tipo);
  object[] args = new object[1];
  args[0] = inicio;
  return tipo.InvokeMember("FindAll", BindingFlags.Default | BindingFlags.InvokeMethod, null, null, args) as T;
}

Ответ 2 · рейтинг 1 · Daniel Pryden

Попробуйте это (обновлено):

public IEnumerable ObjectSource(int inicio, object o) {
    Type type = o.GetType();
    object[] args = new object[] { inicio };
    object result = type.InvokeMember("FindAll",
        BindingFlags.Default | BindingFlags.InvokeMethod, null, o, args);
    return (IEnumerable) result;
}

Лучшим решением было бы поместить ваш метод FindAll в интерфейс, скажем, IFindable, и заставить все ваши классы реализовывать этот интерфейс. Затем вы можете просто привести объект к IFindable и вызвать FindAll напрямую - никакого отражения не требуется.

Ответ 3 · Tiago Schäffer

Дэниел, у меня есть несколько объектов, которые мне нужно привязать к сетке, и этот список содержит более 1000 записей, затем я хочу разбить на 50, и этот объектный источник должен быть универсальным, потому что он вызовет FindAll классов!

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы