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

Как LINQ работает внутри компании?

Мне нравится использовать LINQ для .net, но мне интересно узнать, как это работает внутри?

Кто-нибудь знает это?

Thks.

4b9b3361

Ответ 1

Спрашивается о конкретном аспекте LINQ. Это немного похоже на запрос "Как работает Windows" в противном случае.

Ключевые части LINQ для меня, с точки зрения С#:

  • Деревья выражений. Это представление кода как данных. Например, дерево выражений может представлять собой понятие "взять строковый параметр, вызвать свойство Length на нем и вернуть результат". Тот факт, что они существуют как данные, а не как скомпилированный код, означает, что поставщики LINQ, такие как LINQ to SQL, могут анализировать их и преобразовывать в SQL.
  • Лямбда-выражения. Вот такие выражения:

    x => x * 2
    (int x, int y) => x * y
    () => { Console.WriteLine("Block"); Console.WriteLine("Lambda"); }
    

    Лямбда-выражения преобразуются либо в делегаты, либо в деревья выражений.

  • Анонимные типы. Вот такие выражения:

    new { X=10, Y=20 }
    

    Они все еще статически типизированы, просто компилятор генерирует неизменяемый тип для вас со свойствами X и Y. Они обычно используются с var, который позволяет выводить тип локальной переменной из его выражения инициализации.

  • Выражения запроса. Вот такие выражения:

    from person in people
    where person.Age < 18
    select person.Name
    

    Они транслируются компилятором С# в "обычный" С# 3.0 (т.е. форма, которая не использует выражения запроса). После этого применяется разрешение перегрузки и т.д., Что является абсолютно ключом к возможности использования одного синтаксиса запроса с несколькими типами данных, без компилятора, имеющего какие-либо знания типов, таких как Queryable. Вышеприведенное выражение будет переведено на:

    people.Where(person => person.Age < 18)
          .Select(person => person.Name)
    
  • Методы расширения. Это статические методы, которые можно использовать так, как если бы они были методами экземпляра первого параметра. Например, метод расширения, подобный этому:

    public static int CountAsciiDigits(this string text)
    {
        return text.Count(letter => letter >= '0' && letter <= '9');
    }
    

    можно использовать следующим образом:

    string foo = "123abc456";
    int count = foo.CountAsciiDigits();
    

    Обратите внимание, что в реализации CountAsciiDigits используется другой метод расширения, Enumerable.Count().

Это большинство соответствующих языковых аспектов. Тогда есть реализации стандартных операторов запросов, в LINQ-провайдерах, таких как LINQ to Objects и LINQ to SQL и т.д. У меня есть презентация о том, насколько разумно просто реализовать LINQ to Objects - это на "Talks" на веб-сайте С# в глубину.

Способ работы провайдеров, таких как LINQ to SQL, обычно осуществляется через класс Queryable. По своей сути они преобразуют деревья выражений в другие форматы запросов, а затем создают соответствующие объекты с результатами выполнения этих внепроцессных запросов.

Это покрывает все, что вас интересует? Если есть что-то, о чем вы все еще хотите узнать, просто отредактируйте свой вопрос, и я поеду.

Ответ 2

В простой форме компилятор принимает ваш кодовый запрос и преобразует его в кучу общих классов и вызовов. Ниже, в случае Linq2Sql, динамический SQL-запрос создается и выполняется с использованием DbCommand, DbDataReader и т.д.

Скажите, что у вас есть:

var q = from x in dc.mytable select x;

он преобразуется в следующий код:

IQueryable<tbl_dir_office> q = 
    dc.mytable.Select<tbl_dir_office, tbl_dir_office>(
        Expression.Lambda<Func<mytable, mytable>>(
            exp = Expression.Parameter(typeof(mytable), "x"), 
            new ParameterExpression[] { exp }
        )
    );

Множество дженериков, огромные накладные расходы.

Ответ 3

LINQ в основном представляет собой комбинацию из С# 3.0 дискретных функций:

  • вывод локального переменного типа
  • Авто свойства (не реализованы в VB 9.0)
  • методы расширения
  • лямбда-выражения
  • инициализаторы анонимного типа
  • понимание запроса

Для получения дополнительной информации о поездке туда (LINQ) см. это видео Anders в LANGNET 2008:

http://download.microsoft.com/download/c/e/5/ce5434ca-4f54-42b1-81ea-7f5a72f3b1dd/1-01%20-%20CSharp3%20-%20Anders%20Hejlsberg.wmv

Ответ 4

В основном linq представляет собой смесь некоторых языковых средств (компилятора) и некоторых расширений фреймворка. Поэтому, когда вы пишете запросы linq, они выполняются с использованием соответствующих интерфейсов, таких как IQuerable. Также обратите внимание, что среда выполнения не имеет роли в linq.

Но трудно ответить судье linq в короткий ответ. Я рекомендую вам прочитать какую-нибудь книгу. Я не уверен в книге, в которой рассказывается о внутренних компонентах Linq, но Linq in Action дает хорошие советы об этом.

Ответ 5

У меня есть небольшая программа на С#, которая демонстрирует реализацию LINQ в С#.

class Program
{
    static void Main(string[] args)
    {
        //Eventhough we call the method here, it gets called ONLY when the for loop is executed
        var Cities = LinQFunction(new List<string>() { "Bangalore", "Mysore", "Coorg", "Tumkur", "Kerala", "TamilNadu" });

        //LinQFunction() gets callled now
        foreach(var city in Cities)
        {
            Console.WriteLine(city);
        }
    }

   //This function is called ONLY when the foreach loop iterates and gets the item from the collection
   static IEnumerable<string> LinQFunction(List<string> cities)
    {
        foreach (var item in cities)
        {
            //Return each 'item' at a time 
            yield return item;
        }
    }
}

Используйте соответствующие точки останова.