Abhilash JA Abhilash JA - 1 month ago 5
C# Question

LINQ - "Index was outside the bounds of the array."

I am getting this error:

"Index was outside the bounds of the array."

By using this LINQ query

I want, if A.LogOutTime is returning null then display "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();


How can I solve this?

Answer

The problem is that when the A.LogOutTime is null you place the string "Unknown" which you afterwards split by " " at go to some indexes of the returned IEnumerable. Those indexes do not exist so you get that error.

I suggest that you do something like the following:

  1. Use let so you do not repeat the split each time. Use the C# 6.0 ?. when splitting to avoid a NullReferenceException (in the case that the LogOutTime is null the sections will also still be null)
  2. When assigning to the property check if the LogOutTime is null and if so assign the "Unknown". If it isn't use the result of the split as needed
  3. Use ElementAtOrDefault(n) so you do not access an index that does not exist

So:

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();

Also by checking that LogOutTime is not null I assume it is a string. Instead save it as a DateTime and then you wont have the problems of splitting and accessing some index that does not exist. Use the different properties of DateTime or the ToString() overload where you specify a desired format. For more on the matter: Custom Date and Time Format Strings

Comments