2012-06-26 1 views
10

Я недавно начал изучать лямбда-выражения, и на ум пришел вопрос. Скажем, у меня есть функция, которая требует неопределенного количества параметров. Я бы использовал ключевое слово params для моделирования этого переменного количества параметров.Могут ли параметры [] быть параметрами для лямбда-выражения?

Мой вопрос: могу ли я сделать что-то подобное с выражениями лямбда? Например:

Func<int[], int> foo = (params numbers[]) => 
         { 
          int result; 

          foreach(int number in numbers) 
          { 
           result += numbers; 
          } 

          return result; 
         } 

Если да, два подвопросы представить себя - есть «хороший» способ, чтобы написать такое выражение, и я бы даже хочу написать выражение, как это в какой-то момент?

+0

Возможный дубликат [Переменные параметры в C# Лямбда] (http://stackoverflow.com/questions/3581118/variable-parameters-in-c-sharp-lambda) –

+0

Интересно, можете ли вы на самом деле назвать это выражение Лямбды , Я думаю, что это анонимный метод. –

+1

@YuriyFaktorovich: Это лямбда. The => - лямбда-оператор. –

ответ

13

Ну, вроде. Во-первых, вместо того, чтобы использовать Func<>, вам нужно будет определить пользовательский делегат:

public delegate int ParamsFunc (params int[] numbers); 

Тогда вы могли бы написать следующий лямбда:

ParamsFunc sum = p => p.Sum(); 

и вызвать его с переменным числом аргументов:

Console.WriteLine(sum(1, 2, 3)); 
Console.WriteLine(sum(1, 2, 3, 4)); 
Console.WriteLine(sum(1, 2, 3, 4, 5)); 

Но, честно говоря, на самом деле гораздо более просты в использовании со встроенными делегатами Func<>.

+2

Это именно то, что я искал. Благодарю вас: D –

2

Самое близкое, что я думаю, что вы можете получить что-то вроде этого:

Func<int[], int> foo = numbers[] => 
         { 
          // logic... 
         } 

var result = foo(Params.Get(1, 5, 4, 4, 36, 321, 21, 2, 0, -4)); 

И есть:

public static class Params 
{ 
    public static T[] Get(params T[] arr) 
    { 
     return arr; 
    } 
} 

Но я не могу видеть, как это бьет простой new[] {1, 5, 4, 4, ...}

1

Здесь есть две вещи: общий делегат Func<int[], int> на LHS и выражение лямбда на RHS. Первое не представляется возможным, так как Func<S, T> делегат объявляется как:

public delegate TResult Func<in T, out TResult>(T arg); //ie no params involved 

Вам нужно свой собственный делегат, который принимает params вход, как показано в общепринятом ответ.

Последнее, о чем идет речь в вопросе, также не возможно в C#, , но по причине.

и LHS выражения присваивания является время компиляции вещи (если это не dynamic, конечно, но опять компилятор знает об этом) и его RHS является время выполнения вещи (если, конечно, в случае const с). Компилятор может сделать вывод о том, что напечатано на LHS, но он получает значения в RHS только во время выполнения, то есть при запуске кода. При вводе этого:

Func<int[], int> foo = .... 

foo всегда рассматривается как Func<int[], int>. Это добавит сложности для компилятора, если потребуется расшифровать RHS. Напр.если то, что вы пытаетесь возможно, думать об этом сценарии:

Func<int[], int> foo = (params int[] numbers) => 
        { 
         int result; 

         foreach(int number in numbers) 
         { 
          result += numbers; 
         } 

         return result; 
        }; 

//and later at some other place 
foo = (int[] numbers) => 0; 

//how would you call 'foo' now? 

Вместо когда вы пишете свой собственный делегат, который принимает params, вы сообщаете компилятору непосредственно (то есть известный из LHS).

Из трех функций, параметры именованной поддержки методы, т.е. out/ref, params, необязательный параметра, лямбда-выражение (или даже ранее delegate синтаксиса) поддерживает только out/ref.

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

  • Нет связанных вопросов^_^