2017-08-14 33 views
3

我有这样的方法Resharper转换为LINQ错误?或者是我的代码错

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中的错误?或者我在这里做一些完全愚蠢的事情。

回答

3

是的,resharper还没有理解你的代码,并提出错误的建议。你需要maxMinutesOverdueFound找到最大值,并更新在if连续这个值:

if (overdueStatus.OverdueMinutes > maxMinutesOverdueFound) 
{ 
    maxMinutesOverdueFound = overdueStatus.OverdueMinutes; 
    status = overdueStatus.StatusId; 
} 

如果ReSharper的现在尝试删除此if,只与inital值是不正确的。

因此即使您要更新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; 
相关问题