gpt4 book ai didi

c# - 确保延迟执行将只执行一次,否则

转载 作者:可可西里 更新时间:2023-11-01 08:57:27 24 4
gpt4 key购买 nike

我遇到了一个奇怪的问题,我想知道我应该怎么做。

我有一个返回 IEnumerable<MyClass> 的类这是一个延迟执行。现在,有两个可能的消费者。其中之一对结果进行排序。

请看下面的例子:

public class SomeClass
{
public IEnumerable<MyClass> GetMyStuff(Param givenParam)
{
double culmulativeSum = 0;
return myStuff.Where(...)
.OrderBy(...)
.TakeWhile( o =>
{
bool returnValue = culmulativeSum < givenParam.Maximum;
culmulativeSum += o.SomeNumericValue;
return returnValue;
};
}
}

消费者只调用延迟执行一次,但如果调用多次,结果将是错误的 culmulativeSum不会被重置。我通过单元测试的疏忽发现了这个问题。

解决这个问题的最简单方法就是添加 .ToArray()并以一点开销为代价摆脱延迟执行。

我还可以在消费者类中添加单元测试,以确保他们只调用一次,但这不会阻止 future 编码的任何新消费者遇到这个潜在问题。

我想到的另一件事是让后续执行抛出。有点像

return myStuff.Where(...)
.OrderBy(...)
.TakeWhile(...)
.ThrowIfExecutedMoreThan(1);

显然这不存在。实现这样的事情是个好主意吗?您会如何实现?

否则,如果有我没看到的大粉红色大象,请指出来,将不胜感激。 (我觉得有一个,因为这个问题是关于一个非常基本的场景:|)

编辑:

这是一个糟糕的消费者使用示例:

public class ConsumerClass
{
public void WhatEverMethod()
{
SomeClass some = new SomeClass();
var stuffs = some.GetMyStuff(param);
var nb = stuffs.Count(); //first deferred execution
var firstOne = stuff.First(); //second deferred execution with the culmulativeSum not reset
}
}

最佳答案

您只需将您的方法转换为 iterator 即可解决结果不正确的问题:

double culmulativeSum = 0;
var query = myStuff.Where(...)
.OrderBy(...)
.TakeWhile(...);
foreach (var item in query) yield return item;

可以封装在一个简单的扩展方法中:

public static class Iterators
{
public static IEnumerable<T> Lazy<T>(Func<IEnumerable<T>> source)
{
foreach (var item in source())
yield return item;
}
}

那么在这种情况下你需要做的就是用 Iterators.Lazy 调用包围原始方法体,例如:

return Iterators.Lazy(() =>
{
double culmulativeSum = 0;
return myStuff.Where(...)
.OrderBy(...)
.TakeWhile(...);
});

关于c# - 确保延迟执行将只执行一次,否则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40537516/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com