分别显示每个用户ID的开始和结束时间

时间:2016-02-14 04:46:40

标签: c# list loops for-loop arraylist

我在每个foreach上运行UserId循环但由于某种原因...在我的xml中,只显示了一个userId以及所有开头所有userIds的时间和结束时间。我需要它分别为每个start显示enduserId时间。

所以它看起来像这样:

User2
Start
End
Start
End
Start
End

它需要看起来像这样:

User1
Start
End
Start
End

User2
Start
End

我的代码:

foreach (String userId in request.Users) // request.Users is a Array of UserId's 
{
    List<UserModel> result = // I am making my DataAccess Layer call here.
    UserRecord record = new UserRecord();
    record.UserId = userId;
    record.TimePeriodList = new List<TimePeriod>();
    for (int i = 0; i < result.Count; i += 2)
    {
        TimePeriod timeData = new TimePeriod();
        timeData.StartTime = result[i].TimeDate;
        // if result count is an odd number and this is the last iteration for the UserId
        if (((result.Count & 1) == 1) && (i == result.Count))
            {
                timeData.EndTime = result[i + 1].TimeDate;
            }
            record.TimePeriodList.Add(timeData);
        }
        response.UserRecordList = new List<UserRecord>();
        response.UserRecordList.Add(record);
}

public class GetUserResponse
{
    private List<UserRecord> userRecordList;

    public List<UserRecord> UserRecordList
    {
        get { return userRecordList; }
        set { userRecordList = value; }
    }
}

public class UserRecord
{
    private string userId;
    private List<TimePeriod> timePeriodList;

    public string UserId
    {
        get { return userId; }
        set { userId = value; }
    }

    public List<TimePeriod> TimePeriodList
    {
        get { return timePeriodList; }
        set { timePeriodList = value; }
    }
}

public class TimePeriod
{
    private DateTime startTime;
    private DateTime endTime;

    public DateTime StartTime
    {
        get { return startTime; }
        set { startTime = value; }
    }

    public DateTime EndTime
    {
        get { return endTime; }
        set { endTime = value; }
    }
}

我从DataAccess图层返回的数据如下所示:

UserId    Time        EventType
Test1   xx-xx-xxxx   Start
Test1   xx-xx-xxxx   End
Test2   xx-xx-xxxx   Start

因此,如果有一个奇数,那么User的结束时间默认为DateTime.MinValue

1 个答案:

答案 0 :(得分:2)

如果您单步执行程序,注意变量的状态,您可以轻松发现错误。你的代码几乎可以工作,因为你得到的结果。您看到的唯一结果是最后一个用户......

让我们来看看你的循环:

// you have created a response object here which I had to infer
var response = new GetUserResponse();  // added so my explanation makes sense

foreach (String userId in request.Users) // request.Users is a Array of UserId's 
{
    List<UserModel> result = // I am making my DataAccess Layer call here.
    UserRecord record = new UserRecord();
    // removed stuff that already works
    response.UserRecordList = new List<UserRecord>();
    response.UserRecordList.Add(record);
}

request.Users有两个项目,Test1和Test2。在foreach循环上设置一个断点并开始调试。

如果我们进入foreach循环,那么状态为:

response = instance1 of GetUserResponse
response.UserRecordList = null;
userId = test1

如果我们一直走到第response.UserRecordList = new List<UserRecord>();行,这就是状态:

response = instance1 of GetUserResponse
response.UserRecordList = null;
userId = test1
record = instance1 of UserRecord with values in its fields

当我们跨过下一行时,状态变为

response.UserRecordList = new instance of List<UserRecord>(); // list1

在循环的最后一行之后我们的状态是

response.UserRecordList.Length = 1

现在我们从数组中获取下一个项目,以便userId成为test2。 让我们再次运行到前一行到最后一行,直到现在UserRecordList仍然有1个UserRecord但是如果我们跨过那一行,就会创建一个 NEW 实例,我将其称为list2:

response.UserRecordList = new instance of List<UserRecord>(); // list2

通过此步骤,不再引用先前的list1,稍后将对其进行垃圾回收。在最后一行中添加了用于test2的UserRecord,然后我们就完成了。

显然,创建UserRecords列表的行不应该在foreach循环中。

修复很容易

var response = new GetUserResponse();  // added so my explanation makes sense
response.UserRecordList = new List<UserRecord>(); // init List once

foreach (String userId in request.Users) // request.Users is a Array of UserId's 
{
    List<UserModel> result = // I am making my DataAccess Layer call here.
    UserRecord record = new UserRecord();
    // removed stuff that already works
    // don't init the UserRecordList here, it is done at the start of the loop.
    response.UserRecordList.Add(record);
}