LINQ - "索引超出了数组的范围。"

时间:2016-10-31 12:58:38

标签: c# linq

我收到此错误:

"索引超出了数组的范围。"

使用此LINQ查询

我想,如果A.LogOutTime返回null,则显示" Unknown"。

var listItems = (from A in data orderby A.FirstName 
    select new {
        Action = "Logout", 
        UserName = A.FirstName + " " + A.SurName, 
        ID = A.Id, 
        AccessDate = (A.LogOutTime ?? "Unknown")
                       .Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[0], 
        AccessTimeFrame = (A.LogOutTime ?? "Unknown")
                           .Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[1] 
                       + " " + (A.LogOutTime ?? "Unknown")
                           .Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[2], 
        Comment = "Never delete this Archive" 
 }).Distinct();

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

问题在于,当A.LogOutTimenull时,您将后来被"Unknown"拆分的字符串" "放到返回的{{1}的某些索引处}}。这些索引不存在,因此您会收到该错误。

我建议您执行以下操作:

  1. 使用IEnumerable,这样您每次都不会重复分割。拆分时使用C#6.0 let以避免?. (如果NullReferenceException为空,LogOutTime也将为空)
  2. 分配到媒体资源时,请检查sections是否为LogOutTime,如果是,请指定null。如果它不是根据需要使用拆分的结果
  3. 使用"Unknown",以便您不访问不存在的索引
  4. 所以:

    ElementAtOrDefault(n)

    另外,通过检查var listItems = (from A in data orderby A.FirstName let sections = A.LogOutTime?.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) select new { Action = "Logout", UserName = A.FirstName + " " + A.SurName, ID = A.Id, AccessDate = A.LogOutTime == null ? "Unknown" : sections.ElementAtOrDefault(0), AccessTimeFrame = A.LogOutTime == null ? "Unknown" : (sections.ElementAtOrDefault(1) + " " + sections.ElementAtOrDefault(2)), Comment = "Never delete this Archive" } ).Distinct(); 不是LogOutTime,我认为它是null。而是将其保存为string,然后您就不会遇到拆分和访问某些不存在的索引的问题。使用DateTimeDateTime重载的不同属性,您可以在其中指定所需的格式。有关此问题的更多信息:Custom Date and Time Format Strings

答案 1 :(得分:1)

使用" let"用于将登出时间的部分仅拆分一次的关键字。然后在计算AccessTimeFrame时检查部件的长度。

var listItems = (from A in data
                    let logOutTimeParts = (A.LogOutTime ?? "Unknown").Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
                    orderby A.FirstName
                    select new
                    {
                        Action = "Logout",
                        UserName = A.FirstName + " " + A.SurName,
                        ID = A.Id,
                        AccessDate = logOutTimeParts[0],
                        AccessTimeFrame = logOutTimeParts.Length >= 3 ? logOutTimeParts[1] + " " + logOutTimeParts[2] : "",
                        Comment = "Never delete this Archive"
                    }
    ).Distinct();