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

本文关键字:函数 延迟加载 参数 调用 是否 | 更新日期: 2023-09-27 18:33:20

我想知道是否可以在 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>没有做我需要的。有谁知道任何解决方法或语言功能来支持这种情况?

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

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才会被迫实现。

除了Lazy,您还可以传递Func<int> getTakeCount参数。

懒惰在您访问 .值属性。因此,在你调用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使其工作即可