多参数 linq 表达式如何初始化其参数?

发布于 2024-10-03 16:43:16 字数 422 浏览 1 评论 0原文

在此帖子中,问题的解决方案是:

list.Where ((item,index) =>index

多参数的概念(即(item,index )) 对我来说有点令人困惑,我不知道正确的词来缩小我的谷歌结果范围。那么 1)那叫什么?更重要的是,2)不可枚举变量如何初始化?在这种情况下,index 是如何编译为 int 并初始化为 0 的?

谢谢。

In this post the solution to the problem is:

list.Where((item, index) => index < list.Count - 1 && list[index + 1] == item)

The concept of multi-parameter (ie (item, index)) is a bit puzzling to me and I don't know the correct word to narrow down my google results. So 1) What is that called? And more importantly, 2) How are the non-enumerable variable initialize? In this case how is index compiled as an int and initialized to 0?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

め七分饶幸 2024-10-10 16:43:16

Lambda 表达式有各种语法选项:

() => ... // no parameters
x => ... // single parameter named x, compiler infers type
(x) => ... // single parameter named x, compiler infers type
(int x) => ... // single parameter named x, explicit type
(x, y) => ... // two parameters, x and y; compiler infers types
(int x, string y) => ... // two parameters, x and y; explicit types

这里的微妙之处在于 Where 有一个重载,它接受 Func,表示 值 和 index 分别(并返回匹配的 bool)。因此, Where 实现提供了索引 - 类似于:

static class Example
{
    public static IEnumerable<T> Where<T>(this IEnumerable<T> source,
        Func<T, int, bool> predicate)
    {
        int index = 0;
        foreach (var item in source)
        {
            if (predicate(item, index++)) yield return item;
        }
    }
}

Lambda expressions have various syntax options:

() => ... // no parameters
x => ... // single parameter named x, compiler infers type
(x) => ... // single parameter named x, compiler infers type
(int x) => ... // single parameter named x, explicit type
(x, y) => ... // two parameters, x and y; compiler infers types
(int x, string y) => ... // two parameters, x and y; explicit types

The subtlety here is that Where has an overload that accepts a Func<T, int, bool>, representing the value and index respectively (and returning the bool for the match). So it is the Where implementation that supplies the index - something like:

static class Example
{
    public static IEnumerable<T> Where<T>(this IEnumerable<T> source,
        Func<T, int, bool> predicate)
    {
        int index = 0;
        foreach (var item in source)
        {
            if (predicate(item, index++)) yield return item;
        }
    }
}
百思不得你姐 2024-10-10 16:43:16

使用 LINQ 时,请记住您将方法委托传递给 Where 方法。您调用的 Where 的特定重载采用带有签名 Func 的方法,并将为 list 中的每个项目调用此方法。在内部,这个特定的方法对每个迭代的项目进行计数,并使用该值作为第二个参数调用提供的委托:

var result=suppliedDelegate(item,count)

When using LINQ, remember that you are passing a method delegate to the Where method. The particular overload of Where that you are invoking takes a method with signature Func<T,int,bool>, and will call this method for each item in list. Internally, this particular method is keeping count for every item iterated, and calling the supplied delegate using this value as the second parameter:

var result=suppliedDelegate(item,count)
玩心态 2024-10-10 16:43:16

这个答案有点技术性......请记住,lambda 只是匿名委托(匿名方法)的语法快捷方式。
编辑:它们也可以是表达式树,具体取决于 Where 的签名(请参阅 Marc 的评论)。

list.Where((item, index) => index < list.Count - 1 && list[index + 1] == item)

在功能上相当于

// inline, no lambdas
list.Where(delegate(item, index) { return index < list.Count - 1 && list[index + 1] == item; });

// if we assign the lambda (delegate) to a local variable:
var lambdaDelegate = (item, index) => index < list.Count - 1 && list[index + 1] == item;

list.Where(lambdaDelegate);

// without using lambdas as a shortcut:
var anonymousDelegate = delegate(item, index)
    {
        return index < list.Count - 1 && list[index + 1] == item;
    }

list.Where(anonymousDelegate);

// and if we don't use anonymous methods (which is what lambdas represent):
function bool MyDelegate<TSource>(TSource item, int index)
{
    return index < list.Count - 1 && list[index + 1] == item;
}

list.Where(MyDelegate);

Where 方法具有以下签名:

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate);

相当于:

delegate bool WhereDelegate<TSource>(TSource source, int index);
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, WhereDelegate<TSource> predicate);

这是定义项目和索引的位置。

在幕后, Where 可能会执行类似的操作(只是猜测,您可以反编译查看):

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
{
    int index = 0;

    foreach (TSource item in source)
    {
        if (predicate(index, source))
             yield return item;

        index++;
    }
}

因此,这就是索引初始化并传递给您的委托(匿名、lambda 或其他)的地方。

This answer's a little more technical... Remember that lambdas are simply syntatic shortcuts to anonymous delegates (which are anonymous methods).
Edit: They can also be expression trees depending on the signature of Where (see Marc's comment).

list.Where((item, index) => index < list.Count - 1 && list[index + 1] == item)

is functionally equivalent to

// inline, no lambdas
list.Where(delegate(item, index) { return index < list.Count - 1 && list[index + 1] == item; });

// if we assign the lambda (delegate) to a local variable:
var lambdaDelegate = (item, index) => index < list.Count - 1 && list[index + 1] == item;

list.Where(lambdaDelegate);

// without using lambdas as a shortcut:
var anonymousDelegate = delegate(item, index)
    {
        return index < list.Count - 1 && list[index + 1] == item;
    }

list.Where(anonymousDelegate);

// and if we don't use anonymous methods (which is what lambdas represent):
function bool MyDelegate<TSource>(TSource item, int index)
{
    return index < list.Count - 1 && list[index + 1] == item;
}

list.Where(MyDelegate);

The Where method has the following signature:

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate);

which is equivalent to:

delegate bool WhereDelegate<TSource>(TSource source, int index);
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, WhereDelegate<TSource> predicate);

That's where the item and index are defined.

Behind the scenes, Where may do something like (just a guess, you can decompile to see):

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
{
    int index = 0;

    foreach (TSource item in source)
    {
        if (predicate(index, source))
             yield return item;

        index++;
    }
}

So that's where index is initialized and gets passed to your delegate (anonymous, lambda, or otherwise).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文