Resharper conver to LINQ bug? Or is my code wrong

Viewed 112

I have this method

 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;
}

Status enum

public enum Status
{
    Error = 0,
    Warning = 1,
    Information = 2,
    Ok = 3,
    NeedsConfig = 4,
    Maintenance = 5,
    Disabled = 6,
    Enabled = 7
}

I have unit tests backing up that it works as I expect it to (i.e. it returns from the list the status that is most overdue)

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 suggests that a portion of the loop body can be converted to linq. This is what it proposes:

        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;
        }

As a result it says this line:

maxMinutesOverdueFound = overdueStatus.OverdueMinutes;

Value assigned is not used in any execution path and it can be removed. So i remove it. This makes my loop body this:

foreach (var overdueStatus in overdueMinutes.Where(overdueStatus => lastReceived.AddMinutes(receiveTimeSpanMinutes + overdueStatus.OverdueMinutes) < DateTime.Now)
                                  .Where(overdueStatus => overdueStatus.OverdueMinutes > maxMinutesOverdueFound))
            {
                status = overdueStatus.StatusId;
            }

And now my tests fail. Is this a bug in resharper? Or am I doing something completely stupid here.

1 Answers
Related