我有这个方法
public static Status BiggestOverdue(List<StatusOverdueMinutes> overdueMinutes, DateTime lastReceived, int receiveTimeSpanMinutes)
{
var maxMinutesOverdueFound = 0;
var status = Status.Ok;
if (lastReceived.AddMinutes(receiveTimeSpanMinutes) >= DateTime.Now ||
receiveTimeSpanMinutes == -1)
return Status.Ok;
foreach (var overdueStatus in overdueMinutes.Where(overdueStatus =>
lastReceived.AddMinutes(receiveTimeSpanMinutes +
overdueStatus.OverdueMinutes) < DateTime.Now))
if (overdueStatus.OverdueMinutes > maxMinutesOverdueFound)
{
maxMinutesOverdueFound = overdueStatus.OverdueMinutes;
status = overdueStatus.StatusId;
}
return status;
}
状态枚举
public enum Status
{
Error = 0,
Warning = 1,
Information = 2,
Ok = 3,
NeedsConfig = 4,
Maintenance = 5,
Disabled = 6,
Enabled = 7
}
我有单元测试支持它按我的预期工作(即它从列表中返回最过期的状态)
public void ShouldReturnError()
{
var lastReceived = DateTime.Now.AddMinutes(-30);
var overdueMinutes = new List<StatusOverdueMinutes>
{
new StatusOverdueMinutes {OverdueMinutes = 10, StatusId = Status.Error},
new StatusOverdueMinutes {OverdueMinutes = 7, StatusId = Status.Warning},
new StatusOverdueMinutes {OverdueMinutes = 5, StatusId = Status.Information}
};
const int receiveTimeSpan = 15;
var status = CacheHelper.BiggestOverdue(overdueMinutes, lastReceived, receiveTimeSpan);
Assert.AreEqual(Status.Error, status);
}
[TestMethod]
public void ShouldReturnWarning()
{
var lastReceived = DateTime.Now.AddMinutes(-30);
var overdueMinutes = new List<StatusOverdueMinutes>
{
new StatusOverdueMinutes {OverdueMinutes = 20, StatusId = Status.Error},
new StatusOverdueMinutes {OverdueMinutes = 7, StatusId = Status.Warning},
new StatusOverdueMinutes {OverdueMinutes = 5, StatusId = Status.Information}
};
const int receiveTimeSpan = 15;
var status = CacheHelper.BiggestOverdue(overdueMinutes, lastReceived, receiveTimeSpan);
Assert.AreEqual(Status.Warning, status);
}
[TestMethod]
public void ShouldReturnInformation()
{
var lastReceived = DateTime.Now.AddMinutes(-30);
var overdueMinutes = new List<StatusOverdueMinutes>
{
new StatusOverdueMinutes {OverdueMinutes = 30, StatusId = Status.Error},
new StatusOverdueMinutes {OverdueMinutes = 27, StatusId = Status.Warning},
new StatusOverdueMinutes {OverdueMinutes = 10, StatusId = Status.Information}
};
const int receiveTimeSpan = 15;
var status = CacheHelper.BiggestOverdue(overdueMinutes, lastReceived, receiveTimeSpan);
Assert.AreEqual(Status.Information, status);
}
[TestMethod]
public void ShouldReturnOk()
{
var lastReceived = DateTime.Now.AddMinutes(-10);
var overdueMinutes = new List<StatusOverdueMinutes>
{
new StatusOverdueMinutes {OverdueMinutes = 20, StatusId = Status.Error},
new StatusOverdueMinutes {OverdueMinutes = 15, StatusId = Status.Warning},
};
const int receiveTimeSpan = 15;
var status = CacheHelper.BiggestOverdue(overdueMinutes, lastReceived, receiveTimeSpan);
Assert.AreEqual(Status.Ok, status);
}
Resharper 建议将循环体的一部分转换为 linq。这是它的建议:
foreach (var overdueStatus in overdueMinutes.Where(overdueStatus => lastReceived.AddMinutes(receiveTimeSpanMinutes + overdueStatus.OverdueMinutes) < DateTime.Now)
.Where(overdueStatus => overdueStatus.OverdueMinutes > maxMinutesOverdueFound))
{
maxMinutesOverdueFound = overdueStatus.OverdueMinutes;
status = overdueStatus.StatusId;
}
结果它说这一行:
maxMinutesOverdueFound = overdueStatus.OverdueMinutes;
分配的值未在任何执行路径中使用,可以删除。所以我删除它。这使我的循环体变成这样:
foreach (var overdueStatus in overdueMinutes.Where(overdueStatus => lastReceived.AddMinutes(receiveTimeSpanMinutes + overdueStatus.OverdueMinutes) < DateTime.Now)
.Where(overdueStatus => overdueStatus.OverdueMinutes > maxMinutesOverdueFound))
{
status = overdueStatus.StatusId;
}
现在我的测试失败了。这是 resharper 中的错误吗?或者我在这里做了什么完全愚蠢的事情。
最佳答案
是的,resharper 没有理解您的代码并提示错误。您需要 maxMinutesOverdueFound
来查找最大值,并在 if
中连续更新此值:
if (overdueStatus.OverdueMinutes > maxMinutesOverdueFound)
{
maxMinutesOverdueFound = overdueStatus.OverdueMinutes;
status = overdueStatus.StatusId;
}
如果 resharper 现在尝试删除此
if
并且仅与初始值进行比较,则它是不正确的。因此,即使您将更新 foreach 中的值,LINQ 转换 resharper 建议也是不正确的,因为
Where
仅按初始值过滤。但是您可以将整个查询简化为这样,不需要
foreach
或跟踪变量:StatusOverdueMinutes maxOverdueStatus = overdueMinutes
.Where(odm => lastReceived.AddMinutes(receiveTimeSpanMinutes + odm.OverdueMinutes) < DateTime.Now)
.OrderByDescending(odm => odm.OverdueMinutes)
.FirstOrDefault();
if (maxOverdueStatus == null) return Status.Ok;
return maxOverdueStatus.StatusId;
关于c# - Resharper 转换 LINQ 错误?还是我的代码错了,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45669597/