HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

IndexOrDefault that functions like FirstOrDefault

Submitted by: @import:stackexchange-codereview··
0
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:

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.