C# LINQ延迟执行和嵌套方法

1u4esq0p  于 11个月前  发布在  C#
关注(0)|答案(1)|浏览(122)

我写了以下代码:

List<int> ints = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
int start = 0;
int end = 5;
int limit = 10;
IEnumerable<int> GetRange(List<int> list, int startGR, int endGR)
{
    for (int i = startGR; i < endGR; i++)
    {
        yield return list[i];
    }
}
IEnumerable<int> query = GetRange(ints, start, end).Where(x => x < limit);

void FirstMethod(IEnumerable<int> query1, ref int start1, ref int end1, ref int limit1)
{
    start1 = 4;
    end1 = 9;
    limit1 = 8;
    SecondMethod(query1);

    start1 = 9;
    end1 = 14;
    limit1 = 16;
    SecondMethod(query1);
}

void SecondMethod(IEnumerable<int> query2)
{
    Console.WriteLine(string.Join(", ", query2));
}

FirstMethod(query, ref start, ref end, ref limit);

字符串
控制台打印:

1, 2, 3, 4, 5
1, 2, 3, 4, 5


而不是预期的:

5, 6, 7
10, 11, 12, 13, 14


请解释为什么延迟执行在这里不适用于更新的值。
有没有办法让它像我期望的那样工作?

btxsgosb

btxsgosb1#

GetRange(List<int> list, int startGR, int endGR)将在调用时接收传递的startend的副本(即"by value"),因此这里:

IEnumerable<int> query = GetRange(ints, start, end).Where(x => x < limit);

字符串
在此之后,在FirstMethod中对startend进行的ref操作将没有效果,因此您将拥有一个IEnumerable<int>,它将处理从05的范围,即变量的初始值。
你可以尝试使用LINQ,它的延迟执行和lambda将通过closures捕获局部变量的事实(就像你使用Where(x => x < limit)一样):

IEnumerable<int> query = ints
    .Where((_, index) => index >= start && index <= end)
    .Where(x => x < limit);


虽然我个人并不喜欢这种方法。

相关问题