繁体   English   中英

params []可以作为lambda表达式的参数吗?

[英]Can params[] be parameters for a lambda expression?

我最近开始探索lambda表达式,我想到了一个问题。 假设我有一个需要不确定数量参数的函数。 我会使用params关键字来建模可变数量的参数。

我的问题:我可以用Lambda表达式做类似的事吗? 例如:

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

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

                           return result;
                       }

如果是这样,两个子问题就出现了 - 是否有一种'好'的方式来编写这样的表达式,我甚至想在某个时候写出这样的表达式?

好吧,有点。 首先,您需要定义自定义委托,而不是使用Func<>

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

然后,您可以编写以下lambda:

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<>委托更加直截了当。

我认为你能得到的最接近的东西是这样的:

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,5,4,4 new[] {1, 5, 4, 4, ...}

这里有两件事,LHS上的Func<int[], int>泛型委托和RHS上的lambda表达式。 前者是不可能的,因为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/refparams ,可选参数,lambda表达式(甚至早期的delegate语法)仅支持out/ref

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM