Форум программистов, компьютерный форум, киберфорум
LINQ
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
9 / 9 / 0
Регистрация: 27.01.2013
Сообщений: 248
1

Перечислитель и возвращаемый тип

02.02.2015, 20:01. Показов 1974. Ответов 12
Метки нет (Все метки)

Господа, есть два кусочка кода

C#
1
int[] nums = { 1, -2, 3, 0, -4, 5 };
и

C#
1
2
3
var posNums = from n in nums
                  where n > 0
                  select n;
Собственно вопрос у меня такой, я не могу понять, какой тип данных получается у переменной posNums. Вначале, я решил, что возвращается коллекция, но понял, что это не так. Выходит, что возвращается перечислитель. Однако, насколько я понимаю, то перечислитель занимается "перечислением" набора данных в определенном классе, который содержит эти данные - то есть коллекции или массиве. Тогда в связи с этим возникает вопрос, данный LINQ запрос возвращает определенный класс или что он вообще возвращает ?? При использовании GetType() я получаю, wherearrayiterator, но что это значит я не пойму и гугл тоже. Просветите пожалуйста. Спасибо

ПС
C#
1
2
3
4
5
6
7
8
class a
{
    static void Main()
    {
        int[] x = new int[] { 1, 1, 2, 3, 3, 5, 3, 5, 6, 90 };
        Console.WriteLine(x.GetEnumerator().GetType().Name);
    }
}
В этом коде тоже что-то непонятное возвращается
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.02.2015, 20:01
Ответы с готовыми решениями:

Функции, возвращаемый тип
Как сделать так, что бы функция возвращала разный тип данных, в зависимости от некой глобальной...

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

Возвращаемый тип по умолчанию
Приветствую всех! В книге Р. Лафоре "Объектно-ориентированное программирование в C++" прочитал...

Непонятный возвращаемый тип
Расскажите какой тип должен быть у переменной idRe, чтобы можно было бы присвоить ему значение...

12
Эксперт .NET
5374 / 4160 / 1193
Регистрация: 12.10.2013
Сообщений: 12,073
Записей в блоге: 2
02.02.2015, 20:06 2
Цитата Сообщение от bazyzy Посмотреть сообщение
Просветите пожалуйста
Вы получаете анонимный тип, созданный при выполнении запроса.
1
9 / 9 / 0
Регистрация: 27.01.2013
Сообщений: 248
02.02.2015, 20:08  [ТС] 3
Спасибо, большое. Главное, что все-таки тип данных, а не "голый" перечислитель, который по сути является обычным методом.
0
Заблокирован
02.02.2015, 20:12 4
bazyzy, на примере будет понятнее:
C#
1
2
3
4
5
6
7
8
9
10
11
  List<int> x = new List<int>() { 1, -2, 3, 0, -4, 5 };
            var posNums = x.Where(s => s > 0);
            foreach (var z in posNums)
                Console.Write("{0} ", z);
            Console.WriteLine();
            x.Add(2);
            x.Add(4);
            foreach (var z in posNums)
                Console.Write("{0} ", z);
            Console.WriteLine();
            Console.ReadKey(true);
posNums - не изменяем, но во втором цикле результаты уже другие. Это отложенное выполнение. Поэтому при использовании GetType получаете на первый взгляд странный результат
1
Администратор
Эксперт .NET
13982 / 11341 / 4594
Регистрация: 17.03.2014
Сообщений: 22,929
Записей в блоге: 1
03.02.2015, 00:06 5
bazyzy, в первом случае ты получаешь тип реализующий интерфейс IEnumerable<int>. В данном случае это тип System.Linq.Enumerable.WhereArrayIterator<int>. Важен тут не тип, а интерфейс IEnumerable который обеспечивает ленивый перебор данных. Во втором случае ты получаешь экземпляр IEnumerator в виде типа SZArrayEnumerator, но снова это не важно потому что напрямую мы его не вызываем. Этим занимается foreach.

Цитата Сообщение от insite2012 Посмотреть сообщение
Вы получаете анонимный тип, созданный при выполнении запроса.
Это не так. Анонимный тип там был бы использовании select new { n } например.
1
Эксперт .NET
15555 / 11804 / 3097
Регистрация: 17.09.2011
Сообщений: 19,718
03.02.2015, 13:41 6
Цитата Сообщение от bazyzy Посмотреть сообщение
что он вообще возвращает ?
Определенный класс, который осуществляет обход массива в соответствии с запросом.

Цитата Сообщение от bazyzy Посмотреть сообщение
Главное, что все-таки тип данных, а не "голый" перечислитель, который по сути является обычным методом.
Тут немного наоборот получается: "обычный метод" по сути является "голым" перечислителем, то есть разворачивается компилятором в тип данных.
1
9 / 9 / 0
Регистрация: 27.01.2013
Сообщений: 248
03.02.2015, 15:25  [ТС] 7
Многоуважаемый kolorotur, правильно ли я тогда понимаю, что по LInq запросу возвращается определенный объект, содержащий все данные которые получала переменная диапазона n, и с реализованным методом GetEnumerator(). Но когда я перехожу к foreach, то этот цикл разворачивает примерно следующее
C#
1
2
3
IEnumerator<int> Query = SomeObj.GetEnumerator()
             Query.MoveNext(); Query.Current; 
             ...... итд
0
Администратор
Эксперт .NET
13982 / 11341 / 4594
Регистрация: 17.03.2014
Сообщений: 22,929
Записей в блоге: 1
03.02.2015, 15:29 8
Цитата Сообщение от bazyzy Посмотреть сообщение
правильно ли я тогда понимаю, что по LInq запросу возвращается определенный объект, содержащий все данные которые получала переменная диапазона n
Нет. Ты получаешь объект который вернет тебе по очереди данные в соответствии с запросом когда ты начнешь его перебирать. Ev_Hyper привел пример иллюстрирующий это поведение.
1
9 / 9 / 0
Регистрация: 27.01.2013
Сообщений: 248
03.02.2015, 15:50  [ТС] 9
Да, но ведь этот объект лишь реализует метод GetEnumerator(), а этот метод не является перечислителем. Он лишь возвращает тип интрефейса в котором реализованы методы MoveNext() Reset() Current и т. д. , то есть возвращает перечислитель.
В итоге у меня из-за этого образовалась неразбериха в голове, ведь возвращенный объект не содержит самого перечислителя, а лишь метод, который его предоставляет.
0
Эксперт .NET
15555 / 11804 / 3097
Регистрация: 17.09.2011
Сообщений: 19,718
03.02.2015, 17:05 10
Лучший ответ Сообщение было отмечено bazyzy как решение

Решение

Цитата Сообщение от bazyzy Посмотреть сообщение
правильно ли я тогда понимаю, что по LInq запросу возвращается определенный объект, содержащий все данные которые получала переменная диапазона n, и с реализованным методом GetEnumerator(). Но когда я перехожу к foreach, то этот цикл разворачивает примерно следующее
Правильно, с оговоркой на то, что в перечислителе содержатся не уже извлеченные данные, а инструкции для извлечения этих данных из коллекции.
1
9 / 9 / 0
Регистрация: 27.01.2013
Сообщений: 248
03.02.2015, 17:33  [ТС] 11
Спасибо за ответ, вроде как ясность пришла. Любопытно, а как же тогда методы интерфейса IEnumerator получают доступ к коллекции из которой они извлекают данные ? По идее эта коллекция должна каким-то образом передаваться в объект в котором реализован интерфейс IEnumerable
0
Эксперт .NET
15555 / 11804 / 3097
Регистрация: 17.09.2011
Сообщений: 19,718
03.02.2015, 18:24 12
Лучший ответ Сообщение было отмечено bazyzy как решение

Решение

Цитата Сообщение от bazyzy Посмотреть сообщение
а как же тогда методы интерфейса IEnumerator получают доступ к коллекции из которой они извлекают данные ?
По ссылке

Цитата Сообщение от bazyzy Посмотреть сообщение
По идее эта коллекция должна каким-то образом передаваться в объект в котором реализован интерфейс IEnumerable
Она и передается — вы же вызываете на этой коллекции метод-расширение, тем самым передавая ссылку на коллекцию в классы-итераторы.
1
9 / 9 / 0
Регистрация: 27.01.2013
Сообщений: 248
03.02.2015, 19:12  [ТС] 13
Все, теперь точно разобрался !!!
Всем огромное спасибо за помощь !
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.02.2015, 19:12

Инкапсуляция(возвращаемый тип)
Не могу понять, (3-7), какой возвращаемый тип? void или Secundi? class Secundi { ...

Возвращаемый тип в java
Вопрос такой как создать возвращаемый метод в java я знаю что void это не возвращаемый, а как...

Перегруженные функции. Возвращаемый тип
Добро всем времени суток. Изучаю Р.Лаворе книгу и наткнулся на непонятныий мне аспект. Вот есть...

Перегрузка оператора - возвращаемый тип
class A { private: int x; public: A&amp; operator += (int y); }; A&amp; A::operator...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru