patterncsharpMinor
IndexOrDefault that functions like FirstOrDefault
Viewed 0 times
indexordefaultlikethatfirstordefaultfunctions
Problem
I don't know why this is not in the .NET Library, but I need to be able to use an index against a list and not have it throw an exception if it is outside the bounds of the list.
This is what I came up with:
This is my test:
I would appreciate any advice on missing error handling or if I am reinventing an already existing feature. I also would not mind advice on a way to use an IEnumerable instead of a List with out iterating the IEnumerable more than once.
This is what I came up with:
public static class LinqHelpers
{
public static TListType IndexOrDefault(this List list,
int index)
{
var count = list.Count();
if (index > count -1)
return default(TListType);
if (index < 0)
return default(TListType);
return list[index];
}
}This is my test:
List somelist = new List {"B", "A", "Q", "a", "t", "h"};
for (int i = -100; i < 100; i++)
{
Console.WriteLine(somelist .IndexOrDefault(i));
}I would appreciate any advice on missing error handling or if I am reinventing an already existing feature. I also would not mind advice on a way to use an IEnumerable instead of a List with out iterating the IEnumerable more than once.
Solution
public static TListType IndexOrDefault(this List list, int index)You're extending a concrete type, and the type parameter's name is misleading - it's not the type of the list, it's the type of its items. I'd just call it
T. IList calls it T, so I don't see a problem with T ;)You should be extending an interface, in this case probably an
IEnumerable, like LINQ extension methods do.var count = list.Count();You're iterating the
List through its IEnumerable interface (doesn't apply to List because a List is also an ICollection see @svick's comment below, but in other cases that would be \$O(n)\$ already), and you haven't tried to find anything yet! A List doesn't need to be iterated to retrieve its count, just use the Count property getter, like this:var count = list.Count;Actually this whole block:
var count = list.Count();
if (index > count -1)
return default(T);
if (index < 0)
return default(T);
return list[index];Could be simplified to:
if (index > list.Count - 1 || index < 0)
{
return default(T)
}
return list[index];But that's still extending a
List. You're going to want to extend IEnumerable instead... but the method you're implementing already exists in System.Linq:public static T IndexOrDefault(this IEnumerable source, int index)
{
return source.ElementAtOrDefault(index);
}You're duplicating the functionality of the
IEnumerable.ElementAtOrDefault extension method.Code Snippets
public static TListType IndexOrDefault<TListType>(this List<TListType> list, int index)var count = list.Count();var count = list.Count;var count = list.Count();
if (index > count -1)
return default(T);
if (index < 0)
return default(T);
return list[index];if (index > list.Count - 1 || index < 0)
{
return default(T)
}
return list[index];Context
StackExchange Code Review Q#54574, answer score: 7
Revisions (0)
No revisions yet.