Как работает Linq (за кадром)? - PullRequest
12 голосов
/ 02 декабря 2008

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

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

Ответы [ 6 ]

18 голосов
/ 02 декабря 2008

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

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

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

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

Если вы заинтересованы в эффективной реализации LINQ to Objects, возможно, вас заинтересует выступление, которое я прочитал в DDD в Рединге пару недель назад - в основном, реализация как можно большего количества LINQ to Objects за час. Мы были далеки от завершения до конца, но это должно дать довольно хорошее представление о виде того, что вам нужно сделать (буферизация / потоковая передача, блоки итераторов, трансляция выражений запросов и т. Д.). Видео еще не закончено (и я еще не выложил код для загрузки), но если вам интересно, напишите мне по адресу skeet@pobox.com, и я сообщу вам, когда они закончатся , (Вероятно, я тоже напишу об этом в блоге.)

3 голосов
/ 02 декабря 2008

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

2 голосов
/ 02 декабря 2008

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

2 голосов
/ 02 декабря 2008

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

Это на 100% семантически и почти на 100% синтаксически то же самое, что и LINQ, с отмеченным исключением дополнительных параметров сортировки, использующих 'then' вместо ','.

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

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

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

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

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

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

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

2 голосов
/ 02 декабря 2008
1 голос
/ 02 декабря 2008

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

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

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