В чем разница между моими кодами, когда я использую «динамический» для использования метода AsQueryable?

Сначала я не использую dynamic, я просто использую такой код, и он работает хорошо.

  List<Student> result2 = StudentRepository.GetStudent(sex,age).ToList();
  IQueryable rows2 = result2.AsQueryable();

Но когда я изменяю его на dynamic, это неправильно.

 dynamic result = GetPeopleData(sex,age);
 IQueryable rows = result.AsQueryable();

и я добавляю такой метод, я создаю проект, который показывает, что в списке нет метода AsQueryable. Как его изменить?

 private dynamic GetPeopleData(int sex, int age)
    {
        if(sex>30)
            return StudentRepository.GetStudent(sex,age).ToList();
        else
            return TeacherRepository.GetTeacher(sex, age).ToList();
    }

person flower    schedule 06.03.2015    source источник
comment
Почему вы хотите сделать его динамичным?   -  person Jeroen Vannevel    schedule 06.03.2015
comment
Вы показываете метод GetPeopleData, но вызываете метод GetStudentData. Это правильно?   -  person aush    schedule 06.03.2015
comment
Поскольку я просто хочу получить данные, независимо от того, поступили они от ученика или учителя, я просто хочу изменить их на строки IQueryable и экспортировать эти строки.   -  person flower    schedule 06.03.2015
comment
stackoverflow.com/ вопросы/5311465/ ?   -  person Alexei Levenkov    schedule 06.03.2015
comment
@aush, я поменял. Спасибо.   -  person flower    schedule 06.03.2015
comment
Почитайте про наследование и полиморфизм. Нет причин, по которым вам нужно использовать здесь dynamic. Вам почти никогда не нужно использовать dynamic. Кроме того, какой смысл создавать IQueryable из List<T>? Вызов ToList() в вашем репозитории нетерпеливо извлекает все записи и загружает их в память; вы теряете любую возможность выполнения операторов запросов на сервере.   -  person Mike Strobel    schedule 09.03.2015


Ответы (2)


AsQueryable() — это метод расширения, а они не работают на dynamic.

В зависимости от того, что вы хотите сделать, есть несколько возможных решений:

  1. Не используйте dynamic. Вместо этого заставьте Student и Teacher реализовать общий интерфейс (скажем, IPerson) и используйте его:

    private IReadOnlyList<IPerson> GetPeopleData(int sex, int age)
    {
        if (sex > 30)
            return StudentRepository.GetStudent(sex, age).ToList();
        else
            return TeacherRepository.GetTeacher(sex, age).ToList();
    }
    
    …
    
    var result = GetPeopleData(sex, age);
    IQueryable<IPerson> rows = result2.AsQueryable();
    
  2. Вызовите AsQueryable() как обычный статический метод:

    dynamic result = GetPeopleData(sex, age);
    IQueryable rows = Queryable.AsQueryable(result);
    

Кстати, проверять, является ли секс старше 30 лет, для меня не имеет никакого смысла. Вероятно, вам следует переосмыслить эту часть вашего дизайна.

person svick    schedule 06.03.2015
comment
Возможно, это зависит от того, что здесь означает sex. Я бы предпочел не спрашивать подробности. - person Wiktor Zychla; 06.03.2015
comment
@WiktorZychla Единственная альтернатива, о которой я могу думать, определенно не может быть использована для надежного различия между учениками и учителями. :-) - person svick; 06.03.2015

Это похоже на этот вопрос.

Как сказал @jbtule, анонимные типы являются внутренними, если вы пересекаете границы сборки, динамические не могут разрешить свойство.

Вместо того, чтобы использовать анонимный тип, попробуйте использовать фактический тип или Expando Object.

person Lyly    schedule 06.03.2015
comment
Я не верю, что это применимо, поскольку OP не показал никакого использования анонимных типов... (при условии, что GetTeacher возвращает List<Teacher> аналогично другому). - person Alexei Levenkov; 06.03.2015