C#: действительно ли возможно объявить локальную переменную в анонимном методе?

Ответ AndrewL64 совершенно правильный. Просто хочу отметить, что вы не должны использовать один и тот же идентификатор несколько раз, как в примере ниже:

<h2 id="newsletter_embed_signup">Subscribe to our mailing list</h2>
<h3 id="newsletter_embed_signup">(And get a 10% voucher)</h3>

В противном случае вы столкнетесь с дальнейшими проблемами очень скоро, поэтому используйте классы вместо этого. [ 112]

13
задан Mehrdad Afshari 16 December 2008 в 12:39
поделиться

6 ответов

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

Я задал свой вопрос на форумах MSDN. Посмотрите вопрос и ответ здесь: Многократное использование, Где выражения.

Это может дать Вам общее представление относительно того, как продолжить двигаться, но я должен признать, что пользовательские деревья выражений не для малодушного ;-)

0
ответ дан 1 December 2019 в 19:23
поделиться

Да, почему нет?! В конце концов, это - функция, просто анонимная!

Пример:

 x => { int y = x + 1; return x + y; }

Или альтернативно:

 delegate(int x) {
     int y = x + 1;
     return x + y;
 }

Таким образом, Ваш код может быть написан как:

  ... = linq.Where(e => {
         var count = (from p in db.Orders where p.EnquiryId == e.Id select p).Count();
         return x <= count && count <= y;
  });

ОБНОВЛЕНИЕ: Для разъяснения вещей о комментарии важно знать различие между анонимными методами и лямбда-выражениями. Анонимный метод точно так же, как нормальный метод без явного имени. При компиляции его компилятор генерирует нормальный метод со странным именем Вас вместо этого, таким образом, это не будет иметь никаких специальных ограничений. Однако одно представление анонимного метода является лямбда-выражением. Лямбда-выражения могут быть интерпретированы парой различных способов. Первым является делегат. Таким образом они равны анонимному методу. Вторым является дерево выражений. Этот путь обычно привык LINQ к SQL и некоторым другим поставщикам LINQ. Они не выполняют Ваше выражение непосредственно каким-либо образом. Они анализируют его как дерево выражений и используют дерево в качестве входных данных для генерации эквивалентного SQL-оператора, который будет выполнен на сервере. Это не выполняется как метод, и это не рассмотрело анонимный метод. В этом случае Вы не можете определить локальную переменную, поскольку не возможно проанализировать лямбду как дерево выражений.

26
ответ дан 1 December 2019 в 19:23
поделиться

Да, можно сделать точно, что Вы хотите в Linq к объектам и Linq к SQL.

Существует a let в Linq, позволяя Вам дать имя промежуточному результату посреди Вашего запроса, как Вы хотите. На основе Вашего примера:

... = from e in linq 
      let count = (from p in db.Orders where p.EnquiryId == e.Id select p).Count()
      where (x <= count) && (count <= y)
      select e;

Между прочим, я думаю, что было что-то синтаксически ошибочное о Вашем исходном примере, который легче определить когда count просто имя:

where (x <= count) && /* <= */ (count <= y);
7
ответ дан 1 December 2019 в 19:23
поделиться

При использовании Linq для SQL Вы не сможете использовать ответ Mehrdad Afshari. Вашими выражениями LINQ должны быть Деревья выражений, и они не поддерживают анонимный синтаксис делегата.

И при этом Вы не сможете создать своего делегата в другом месте и назвать его из лямбды - Linq к SQL только позволяет определенным операциям быть выполненными в теле запроса, и вызов делегата не является одним из них.

Ваш лучший выбор, принимая Вы используете Linq для SQL (как это появляется, учитывая Ваш пример), должен снизить количество в одном запросе, затем получить переменную количества в запросе, который требует количества.

2
ответ дан 1 December 2019 в 19:23
поделиться

Где метод берет Func поэтому, что Вы являетесь передающими там во второй части ins't на самом деле метод, но просто bool выражение. Мое предложение состояло бы в том, чтобы иметь фактический метод, который возвращает bool, который берет в параметрах, в которых Вы нуждаетесь, и в Вашем вызове к, Где метод Вы просто делаете что-то вроде этого Где (p => MyMethod (p...))

1
ответ дан 1 December 2019 в 19:23
поделиться

С небольшими знаниями в Схеме Вы знали бы, что 'позволяют', просто сахар синтаксиса для определения лямбды и вызова его.

Таким образом с тем знанием, позволяет, видят, как оно может быть сделано.

(count => x <= count && count <= y)
  ((from p in db.Orders 
    where p.EnquiryId == e.Id 
    select p).Count())

В качестве награды это похоже на Схему также :)

Отказ от ответственности: Я не протестировал этот отрывок, но нет никакой причины, он не должен работать. Лично, я просто использовал бы конструкцию, которой 'позволяют', обеспеченную в LINQ.

Обновление:

Это не работает... :(

0
ответ дан 1 December 2019 в 19:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: