2012-01-30 4 views
14

Мне нужно передать запрос лямбды в качестве параметра, код нижеуказанных является образцом, и я интересно найти орудие для него, есть образцы: некоторые вещи, как это:Есть ли способ передать лямбда-выражение как переменную или аргумент?

var expr1 = Where(n => n > 6).OrderBy(n => n % 2 == 0).Select(n => n); 
var expr2 = TakeWhile((n, index) => n >= index)); 

и использовать его, как это :

public void UseLambda<T> (IEnumerable<T> source , lambda Expr){ 

var items= Expr.Compile(source); 

foreach(var item in items) 
    Console.Writeline(item.ToString()); 
} 

public void Main(){ 
    List<int> numbers = new List<int> { 10, 24, 9, 87, 193, 12, 7, 2, -45, -2, 9 }; 
    var expr1 = Where(n => n > 6).OrderBy(n => n % 2 == 0).Select(n => n); 
    UseLambda(numbers, expr1); 
} 

Есть ли у кого-нибудь есть идеи?

ответ

8

Если вы определяете LINQ выражения, как это:

Func<IEnumerable<int>, IEnumerable<int>> expr1 = 
       l => l.Where(n => n > 6).OrderBy(n => n % 2 == 0).Select(n => n); 

Func<IEnumerable<int>, IEnumerable<int>> expr2 = 
       l => l.TakeWhile((n, index) => n >= index); 

и ваш метод UseLambda как:

public void UseLambda<T> (IEnumerable<T> source 
          ,Func<IEnumerable<T>, IEnumerable<T>> lambda) 
{ 
    var items= lambda(source); 

    foreach(var item in items) 
     Console.Writeline(item.ToString()); 
    } 
} 

Тогда вы я думаю, что у вас есть то, что вы ищете.

+2

Существует ошибка в определения Expr1, expr2: «System.Collections.IEnumerable» не содержит определения для «где» и не метод расширения "Где принимать первый аргумент типа«System.Collections. IEnumerable '(вам не хватает директивы using или ссылки на сборку?) – Saeid

+2

необходимо изменить на: Func , ...... – Saeid

+0

Спасибо за редактирование Saeid. – Samuel

0

Ну лямбда не что иное, как делегат, так что вы могли бы иметь метод, как это:

public void DoIt(IEnumerable a, Action<IEnumerable> performThis) 
{ 
    performThis(a); 
} 

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

8

Проверить Func(Of T, TResult) Delegate (MSDN)

using System; 

public class LambdaExpression 
{ 
    public static void Main() 
    { 
     Func<string, string> convert = s => s.ToUpper(); 

     string name = "Dakota"; 
     Console.WriteLine(convert(name)); 
    } 
} 

Из MSDN

Основной тип лямбда-выражения является одним из общих Func делегатов. Это приводит к тому, что можно передать выражение лямбда как параметр без явного назначения его делегату. В частности, поскольку многие методы типов в пространстве имен System.Linq имеют параметры Func (Of T, TResult), вы можете передать эти методы лямбда-выражению без явного создания экземпляра делегата Func (Of T, TResult).

EDIT

Возможное решение для Вашего случая

static void Main(string[] args) 
{ 
    List<int> numbers = new List<int> { 10, 24, 9, 87, 193, 12, 7, 2, -45, -2, 9 }; 
    Func<IEnumerable<int>, IEnumerable<int>> expr = n => n.Where(n1 => n1 > 6).OrderBy(n1 => n1 % 2 == 0).Select(n1 => n1); 
    UseLambda<int>(numbers, expr); 
} 
private static void UseLambda<T>(List<T> numbers, 
           Func<IEnumerable<T>, 
           IEnumerable<T>> expr) 
{ 
    var values = expr(numbers); 
    foreach (var item in values) { 
     Console.WriteLine(item); 
    } 
} 
1

ли вы имеете в виду что-то вроде этого:

public void UseLambda<T> (IEnumerable<T> source , Func<T, bool> where, Func<T, bool> order) 
{ 
    if(source != null) 
    { 
     IOrderedEnumerable<T> orderBy = source.Where(where).OrderBy(order); 
     foreach (T value in orderBy) 
     { 
      Console.WriteLine(value); 
     } 
    } 
} 

Так что вы могли бы назвать это как так:

UseLambda(numbers, x => x > 6, x => x % 2 == 0); 
0
public void UseLambda<T>(IEnumerable<T> source, Expression<Func<IEnumerable<T>, IEnumerable<T>>> expr) 
{ 
    var items = expr.Compile(); 

    foreach (var item in items.Invoke(source)) 
    { 
     Console.WriteLine(item.ToString()); 
    } 
} 


public void Main() 
{ 
    Expression<Func<IEnumerable<int>, IEnumerable<int>>> expr = s => s.Where(n => n > 6).OrderBy(n => n % 2 == 0).Select(n => n); 
    var list = new List<int> { 10, 24, 9, 87, 193, 12, 7, 2, -45, -2, 9 }; 

    UseLambda(list, expr); 
} 
Смежные вопросы