Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#调用函数后是否可以延迟加载函数参数?_C#_.net_Lazy Loading_Lazy Evaluation_Lazy Initialization - Fatal编程技术网

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

c#调用函数后是否可以延迟加载函数参数?,c#,.net,lazy-loading,lazy-evaluation,lazy-initialization,C#,.net,Lazy Loading,Lazy Evaluation,Lazy Initialization,我想知道在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

我想知道在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
var a=可枚举范围(1,10);
int-take=5;
var lazyTake=新懒惰(()=>take);
//在这里,我仍然不在Enumerable上迭代,我希望函数Take的参数在我开始迭代时被初始化
VarB=a.Take(lazyTake.Value);
//这里我初始化(更改)参数take的值
取=6;
Console.WriteLine(b.ToList().Count);//我想要b有6个元素,但它是5

这里,
Lazy
不是在做我需要的事情。有人知道支持这种情况的解决方法或语言功能吗?

Lazy在您访问.value属性时意识到它的价值。所以当你调用a.Take时,你已经得到了实际的int值5。此时更改
take
变量没有任何帮助,惰性消失了


您需要的函数将采用
惰性
,而不是
T
。如果您了解如何实现
IEnumerable
,那么您可能可以轻松编写一个,但据我所知,该框架中没有内置任何东西适合您的场景。

一切正常,值正在缓慢初始化,但问题是在调用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 a=可枚举范围(1,10);
int-take=5;
//在这里,我仍然不在Enumerable上迭代,我希望函数Take的参数在我开始迭代时被初始化
Func getResult=()=>a.Take(Take);
//这里我初始化(更改)参数take的值
取=6;
Console.WriteLine(getResult().ToList().Count);
编辑:不能对lambda使用var,只需使用Func使其工作

public IEnumerable Take(此IEnumerable源,惰性计数){
public 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;
}
var takeSequence=source.Take(count.Value); foreach(takeSequence中的var项目)收益返回项目; }
这完全是懒惰。此函数体仅在开始枚举时执行,因为这是一个迭代器方法。只有这样,懒惰的
计数才会被强制具体化


您也可以传递
Func getTakeCount
参数,而不是
Lazy

谢谢Gusman!这很有趣,但问题是在我的示例中,变量
b
不再是
IEnumerable
,而是
Func
。我仍然希望
b
具有类型
IEnumerable
。假设
b
是一个类变量,您想用
IEnumerable
初始化它,但仍然不知道需要使用多少元素;你的意思是这样的:
public IEnumerable Take(这个IEnumerable源代码,惰性计数){return source.Take(count.Value);}
几乎-执行
return source.Take(count.Value)
会做完全相同的事情。您将需要实际实现IEnumerator(使用yield语句),以便在实际枚举整个序列之前不会解析延迟。哇!这是令人惊讶的工作!谢谢!这里让我惊讶的是,当我使用
返回source.Take(count.value)
将对惰性变量
count
进行求值,但在您的实现中,求值将推迟到枚举被迭代为止!有什么解释吗?这是一个迭代器方法。它的执行是通过枚举返回值来驱动的。您能详细介绍一下它的具体用例吗@usr已经给出了一个有效的答案,但我很好奇在什么情况下您希望能够在事后更改参数值。或者:这只是一个展示你想要的行为的玩具示例,但在实际用例中,您的值不会随时间变化,但计算起来可能会很昂贵?@ShinNoNoir您可以猜到的用例确实是在计算
take
数字时,这是一项昂贵的任务,您只想在使用对象时才这样做(在本例中为
b
,但它可以是类属性)。