我有一个对象(触发器),其中包含一个名为
GetNextFireTime(DateTimeOffset after)
,在给定输入后触发器下次触发时返回。我的目标是,给定一个未知大小的时间列表的输入
n
,以及开始时间,以确保时间列表与第一个时间匹配
n
触发器在开始时间后触发的次数。这样很容易做到
void Test(ITrigger trigger, DateTimeOffset start, DateTimeOffset[] expectedFireTimes){
var nextFire = startTime;
foreach (var expectedFire in expectedFireTimes){
nextFire = trigger.GetFireTimeAfter(nextFire);
Assert.That(nextFire, Is.EqualTo(expectedFire));
}
}
然而,我后来决定,我宁愿将测试结果视为一个单一的断言,而不是逐一断言元素,这样,如果前两次射击是正确的,但第三次射击是错误的,测试结果就会清楚地显示出预期的结果和发现的结果。这可以通过创建一个列表而不是在循环中断言来实现:
void Test(ITrigger trigger, DateTimeOffset start, DateTimeOffset[] expectedFireTimes){
var nextFire = startTime;
var upcomingFireTimes = new List<DateTimeOffset>();
foreach (var expectedFire in expectedFireTimes){
nextFire = trigger.GetFireTimeAfter(nextFire);
upcomingFireTimes.Add(nextFire);
}
Assert.That(upcomingFireTimes, Is.EqualTo(expectedFireTimes));
}
这也行得通,但这让我开始思考是否可以通过Linq来实现。
Linq是否有方法创建一个列表,其中每个元素都是基于初始种子和前一个元素计算的?
我能想到的最接近的是
Aggregate()
,它接受一个种子和一个函数,但只返回一个值,我必须将单个元素存储在函数内的列表中,这使得它与
foreach
上面的循环:
var upcomingFireTimes = new List<DateTimeOffset>();
expectedFireTimes.Aggregate(
startTime,
(seed, _) => {
var nextfire = trigger.GetFireTimeAfter(seed);
upcomingFireTimes.Add(nextFire);
return nextFire;
});
我的目标是一个单行Linq方法,而不是最终只返回
最后的
计算值,如
聚合()
做,返回
全部的
沿途计算的值,如下所示:
var upcomingFireTimes = expectedFireTimes.SomeLinqMethod(
startTime,
(seed, _) => trigger.GetFireTimeAfter(seed));