c#是否可以在调用函数后延迟加载函数参数?

c# is it possible to lazy load function parameter after calling the function?

我想知道在 C# 中是否可以在调用函数后延迟加载函数的参数。事实上,我只想在使用函数的输出时加载函数的参数。 我试着用下面的例子来解释我的意思:

        var a = Enumerable.Range(1, 10);
        int take = 5;
        var lazyTake = new Lazy<int>(() => take);

        // here I still don't iterate on Enumerable, I want the parameter of function Take be initialized later when I start iterating
        var b = a.Take(lazyTake.Value);

        // here I initialize (change) the value of parameter take
        take = 6;   

        Console.WriteLine(b.ToList().Count);  // I want b to have 6 elements but it's 5

这里 Lazy<int> 没有做我需要的。有谁知道支持这种情况的任何解决方法或语言功能?

Lazy 在您访问 .Value 属性 时意识到它的价值。所以当你调用 a.Take 时,你得到了实际的 int 值 5。此时更改 take 变量无济于事,懒惰消失了。

您需要一个接受 Lazy<T> 而不是 T 的函数。如果您了解如何实现 IEnumerable<T>,您可能可以轻松地编写一个框架,但据我所知,框架中没有任何内容适合您的场景。

一切正常,值正在延迟初始化,但问题是当您调用 a.take(lazyTake.Value) 时正在计算值,因为您将它作为参数传递给功能,必须对其进行评估。

你能做的最好的事情就是用一个 lambda 包围它并在最后执行 lambda:

    var a = Enumerable.Range(1, 10);
    int take = 5;

    // here I still don't iterate on Enumerable, I want the parameter of function Take be initialized later when I start iterating
    Func<IEnumerable<int>>  getResult = () => a.Take(take);

    // here I initialize (change) the value of parameter take
    take = 6;   

    Console.WriteLine(getResult().ToList().Count);

编辑:不能将 var 用于 lambda,只需使用 Func 使其工作

public static IEnumerable<T> Take<T>(this IEnumerable<T> source, Lazy<int> count) { 
    var takeSequence = source.Take(count.Value);
    foreach (var item in takeSequence) yield return item;
}

这完全是懒惰。这个函数的主体只会在你开始枚举时执行,因为这是一个迭代器方法。只有这样,懒惰的count才会被强制物化

您也可以传递 Func<int> getTakeCount 参数而不是 Lazy