I safely search a list for an object like this:
var someResult = myList.FirstOrDefault(x=>x.SomeValue == "SomethingHere");
If there are no objects that match my criteria then someResult
is going to be null.
But if I only have the index of the object I want, things are not so nice. I seem to have to so something like this:
try
{
var someResult = myList[4];
}
catch (ArgumentOutOfRangeException)
{
someResult = null;
}
I admit that is not terrible to have to write. But it seems to me that there should be a way to just have the list return null if the index ends up being bogus.
Is there away to have a one (or two) line look up using existing .net methods?
(I know I could easily write an extension method, but I am wondering if there is a built in way to do this.)
The index() method searches for the first occurrence of the given item and returns its index. If specified item is not found, it raises 'ValueError' exception. The optional arguments start and end limit the search to a particular subsequence of the list.
LINQ does not have an IndexOf method. So to find out index of a specific item we need to use FindIndex as int index = List. FindIndex(your condition); 0.
I think you want C.B.s suggestion of ElementAtOrDefault
- go vote it up.
I have a few other points to add...
Regarding your try/catch solution:
I admit that is not terrible to have to write.
Please don't use exceptions for this. Your approach is more verbose, exceptions are slow so you will get poor performance, and exceptions should only be used for exceptional situations.
It's also fairly easy to write this without LINQ by using the conditional operator:
var someResult = myList.Count > 4 ? myList[4] : null;
You may be able to use the LINQ extension .ElementAtOrDefault() to achieve what you want.
List<Foo> foos = new List<Foo>();
Foo element = foos.ElementAtOrDefault(4);
However, you need to be careful that your generic type to List<T>
is a reference type or a string, so the "default" returned to you is actually null. The default you get back is default(T).
Yes, you can also use LINQ when you only have the index:
var someResult = myList
.Select((x, i) => new { X = x, Index = i })
.FirstOrDefault(x => x.Index == 4);
Enumerable.Select Method (IEnumerable, Func)
Projects each element of a sequence into a new form by incorporating the element's index.
C B's answer wins, but I can compete for second place, right?
var someResult = myList.Skip(4).FirstOrDefault();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With