2010-07-31 2 views
2

Немного о Linq. У меня есть следующий код:Параметры запроса Linq

(Пожалуйста, извините жалкий размер набора данных)

class Program 
{ 
    static void Main(string[] args) 
    { 
     var employees = new List<Employee> 
          { 
           new Employee 
            { 
             Name = "Bill Bailey", 
             EmployeeCode = 12345, 
             Department = "Comedy Lab", 
             DateOfBirth = DateTime.Parse("13/01/1964"), 
             CurrentEmployee = true 
            }, 
           new Employee 
            { 
             Name = "Boris Johnson", 
             EmployeeCode = 56789, 
             Department = "Cycling Dept.", 
             DateOfBirth = DateTime.Parse("19/06/1964"), 
             CurrentEmployee = true 
            }, 
           new Employee 
            { 
             Name = "Bruce Forsyth", 
             EmployeeCode = 5, 
             Department = "Comedy Lab", 
             DateOfBirth = DateTime.Parse("22/03/1928"), 
             CurrentEmployee = false 
            }, 
           new Employee 
            { 
             Name = "Gordon Brown", 
             EmployeeCode = 666, 
             Department = "Backbenches", 
             DateOfBirth = DateTime.Parse("20/02/1951"), 
             CurrentEmployee = false 
            }, 
           new Employee 
            { 
             Name = "Russell Howard", 
             EmployeeCode = 46576, 
             Department = "Comedy Lab", 
             DateOfBirth = DateTime.Parse("23/03/1980"), 
             CurrentEmployee = false 
            } 
          }; 

     Func<Employee, bool> oapCalculator = (employee => employee.DateOfBirth.AddYears(65) < DateTime.Now); 

     var oaps1 = employees.Where(oapCalculator); 
     var oaps2 = (from employee in employees 
        where oapCalculator(employee) 
        select employee); 

     oaps1.ToList().ForEach(employee => Console.WriteLine(employee.Name)); 
     oaps2.ToList().ForEach(employee => Console.WriteLine(employee.Name)); 

     Console.ReadLine(); 
    } 

    class Employee 
    { 
     public string Name { get; set; } 
     public int EmployeeCode { get; set; } 
     public string Department { get; set; } 
     public DateTime DateOfBirth { get; set; } 
     public bool CurrentEmployee { get; set; } 
    } 
} 

У меня есть несколько вопросов:

Насколько я могу судить, оба признаков Запросы Linq делают то же самое (возможно, черная магия).

  1. Будут ли они оба скомпилированы до того же ИЛ?
  2. Если нет, то почему, и что было бы наиболее эффективным, учитывая значительный объем данных?
  3. Каков наилучший способ проверки эффективности запросов Linq? Таймеры производительности или что-то встроенное?
  4. Является ли лямбда-выражение предпочтительным методом, поскольку он является наиболее кратким?
  5. В отделе лямбды, боясь луддитов, стоит ли погрузиться и обучить их или использовать синтаксис SQL-esque?

Благодаря

+0

Так как вы используете лямбда-выражения в обоих методах, я не уверен, что ваши вопросы 4 и 5 клонит. Вероятно, вы могли бы переписать вторую версию без лямбды, и я подозреваю, что многие утверждают, что она будет более чистой и читаемой. –

ответ

3

Re

var oaps1 = employees.Where(oapCalculator); 

против

var oaps2 = (from employee in employees 
      where oapCalculator(employee) 
      select employee); 

Существует небольшая разница, в частности, вокруг where oapCalculator(employee). Второй запрос отображается:

var oaps2 = employees.Where(employee => oapCalculator(employee)); 

так это дополнительного слой делегата, и также берут на себя (небольшие) непроизводительные издержки захвата класса из-за закрытия по переменной oapCalculator, и разыгрывать это на итерации. Но в остальном они одинаковы. В частности, Select тривиально удален (в соответствии со спецификацией).

В общем, используйте то, что лучше всего в любом сценарии. В этом случае либо кажется прекрасным, , но вам будет проще использовать .Where и т. Д., Если вы регулярно занимаетесь сценариями, в которых участвуют делегаты, или Expression.

0

Оба запроса LINQ эквивалентны. Второй использует синтаксический сахар, который компилятор переводит в выражение, подобное первому запросу перед компиляцией. Что касается того, что предпочтительнее, используйте то, что кажется более читаемым для вас и вашей команды.

2

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

1 и 2: Разберите и узнайте! :) http://www.red-gate.com/products/reflector/

: Профиль вашего приложения.Это ответ на любой решающий вопрос, если вы не работаете с алгоритмом (математические доказательства, big-o). Инструменты профилирования встроены в VS.

: Что вы предпочитаете? Как насчет ваших коллег? Это звучит как статистический вопрос, который потребует опроса

: Как и у 4, попробуйте его и узнайте! Как вы, возможно, испытали, евангелизация новых методов вашим коллегам научит вас столько, сколько она научит их.

Я нашел, что у меня было около 50% успеха с преподаванием общего делегирования/использования лямбда. Я убедился, что придумал практические примеры из моего тестового кода производства и показал, как эквивалентный императивный код имел много дублирования.

Я попытался пройти через бесплатные видео SICP с моей командой (будучи действительно открывающимся для рефакторинга), и я нашел это довольно тяжелой продажей. LISP не является самым привлекательным языком для большинства программистов ...

http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/

+0

Пункт 5 является важным, преподавание и объяснение концепции - это, безусловно, лучший способ узнать что-то и укрепить его в своем уме! – NibblyPig

+0

Вполне, я мог бы использовать этот код, чтобы определить, сколько сотрудников возраста OAP находится в компании. Они должны помнить об этом ... – fletcher

Смежные вопросы