Подтвердить что ты не робот

Как работает Linq (за кулисами)?

Я думал о создании чего-то вроде Linq для Lua, и у меня есть общее представление о том, как работает Linq, но задавался вопросом, была ли хорошая статья или кто-то мог объяснить, как С# делает Linq возможным

Примечание. Я имею в виду за кулисами, например, как он генерирует привязки кодов и все такое, а не синтаксис конечных пользователей.

4b9b3361

Ответ 1

Трудно ответить на вопрос, потому что LINQ - это очень много разных вещей. Например, придерживаясь С#, задействованы следующие вещи:

  • Выражения запросов "предварительно обработаны" в "С# без выражений запроса", которые затем скомпилируются в обычном режиме. Часть выражения запроса спецификации очень короткая - это в основном механический перевод, который не предполагает ничего о реальном значении запроса, кроме "order by, переведенный в OrderBy/ThenBy/etc".
  • Делегаты используются для представления произвольных действий с определенной сигнатурой в качестве исполняемого кода.
  • Деревья выражений используются для представления одной и той же вещи, но как данные (которые могут быть рассмотрены и переведены в другую форму, например SQL)
  • Лямбда-выражения используются для преобразования исходного кода в делегаты или деревья выражений.
  • Методы расширения используются большинством провайдеров LINQ для объединения вызовов статических методов. Это позволяет простому интерфейсу (например, IEnumerable<T>) эффективно получать намного больше мощности.
  • Анонимные типы используются для прогнозов - там, где у вас есть некоторая разрозненная коллекция данных, и вам нужны биты каждого из аспектов этих данных, анонимный тип позволяет вам собирать их вместе.
  • Неявно введенные локальные переменные (var) используются, прежде всего, при работе с анонимными типами, для поддержания статически типизированного языка, где вы не можете "явно говорить" имя типа явно.
  • Блоки Iterator обычно используются для реализации запросов в процессе, например. для LINQ to Objects.
  • Тип вывода используется для того, чтобы сделать все это более гладко - в LINQ существует много общих методов, и без вывода типа было бы очень больно.
  • Генерация кода используется для превращения модели (например, DBML) в код
  • Частичные типы используются для обеспечения расширяемости сгенерированного кода
  • Атрибуты используются для предоставления метаданных поставщикам LINQ

Очевидно, что многие из них используются не только LINQ, но и другие технологии LINQ будут зависеть от них.

Если вы можете дать больше информации о том, какие аспекты вас интересуют, мы можем предоставить более подробную информацию.

Если вы заинтересованы в эффективном внедрении LINQ to Objects, вы можете быть заинтересованы в разговоре, который я дал в DDD в Чтении пару недель назад, - в основном, используя как можно больше LINQ для объектов через час. Мы были далеки от завершения к концу, но это должно дать довольно хорошее представление о том, что вам нужно делать (и буферизации/потоковой передаче, блоках итератора, переводе выражения запроса и т.д.). Видео еще не подняты (и я еще не добавил код для скачивания), но если вам интересно, напишите мне письмо по адресу [email protected], и я сообщу вам, когда они встанут, (Вероятно, я тоже расскажу об этом.)

Ответ 2

Mono (частично?) реализует LINQ и является открытым исходным кодом. Может быть, вы могли бы изучить их реализацию?

Ответ 4

Возможно, мой LINQ для схемы R6RS предоставит некоторые идеи.

Он на 100% семантически и почти на 100% синтаксически совпадает с LINQ с отмеченным исключением дополнительных параметров сортировки с использованием "then" вместо ",".

Некоторые правила/предположения:

  • Только для списков, поставщиков запросов.
  • Не ленивое, но нетерпеливое понимание.
  • Нет статических типов, так как Scheme не использует их.

Моя реализация зависит от нескольких основных процедур:

  • map - используется для 'Выбрать'
  • фильтр - используется для "Где"
  • flatten - используется для 'SelectMany'
  • sort - процедура сортировки с несколькими ключами
  • groupby - для группировки конструкций

Остальная структура построена с использованием макроса.

Привязки сохраняются в списке, который помечен связанными идентификаторами для обеспечения гигиены. Связывание извлекается и восстанавливается локально, где когда-либо происходит выражение.

Я отслеживал прогресс в моем блоге который может дать некоторое представление о возможных проблемах.

Ответ 5

Для дизайнерских идей взгляните на c omega, исследовательский проект, который привел к появлению Linq. Linq - более прагматичная или орошаемая версия c omega, в зависимости от вашей перспективы.

Ответ 6

В блоге Мэтта Уоррена есть все ответы (и пример реализации IQueryable поставщика, чтобы дать вам головной убор):

http://blogs.msdn.com/mattwar/