Reputation: 43833
In IEnumerable.First function, how do I handle the case if there are no matches? Currently it just crashes...
MySPListItem firstItem = itemCollection.First(item => !item.isFolder);
if (firstItem != null)
{
TreeNode firstNode = GetNodeByListItem(my_treeview.Nodes, firstItem, ReportObject);
if (firstNode != null)
{
ReportObject.log("Selecting the first PDF");
selectPDF(my_treeview, firstNode, queryStr_param);
}
}
Error Message:
Sequence contains no matching element
Stacktrace: at System.Linq.Enumerable.First[TSource](IEnumerable1 source, Func
2 predicate)
Upvotes: 10
Views: 17314
Reputation: 35696
Ok, If it is exceptional for there to be no first,
try
{
var first = enumerable.First();
}
catch (InvalidOperationException)
{
// Oops, that was exceptional.
}
If you anticipate that there may be no first in some valid situations,
var first = enumerable.FirstOrDefault();
if (first == default(someType)) // null for reference types.
{
// Ok, I need to deal with that.
}
Upvotes: 29
Reputation: 18031
Replace First by FirstOrDefault :
MySPListItem firstItem = itemCollection.FirstOrDefault(item => !item.isFolder);
Upvotes: 3
Reputation: 14870
While you do a null
check on the find, you don't in your predicate. The line
foundItem = itemCollection.Find(item => item.item.ID == PDFID);
Might throw an exception it item
is null
(have you inserted an null
item in the collection?) or item.item
is null
(are you sure it's always there?).
You could do:
foundItem = itemCollection.Find(item => item != null &&
item.item != null &&
item.item.ID == PDFID);
More chatty, but you won't get a NullReferenceException
.
Edit Well you changed your question. Now you do First
. The First
method will throw an exception if nothing is found. Use FirstOrDefault
instead which will return null
for a class or the default value for a struct
.
foundItem = itemCollection.FirstOrDefault(item => item != null &&
item.item != null &&
item.item.ID == PDFID);
Upvotes: 7
Reputation: 34489
It shouldn't throw an exception, you need to handle the case where it returns default(T). You might be getting a NullReferenceException because you're not handling the case where it returns null. For example:
IEnumerable<Cars> cars = GetCars();
Car car = cars.Find(c => c.Model == "Astra");
if(car != null)
{
// You found a car!
}
If you were doing the same for a struct, you'd check for it's default instead. Ints for example would be a 0:
int[] ints = new int[] { 1, 4, 7 };
int myInt = ints.Find(i => i > 5);
if(myInt != 0) // 0 is default(int)
{
// You found a number
}
Upvotes: 0
Reputation: 70718
Check if the result is null
:
if (result == null)
{
Console.WriteLine("Not found");
}
There is a clear example demonstrating what to do if the item is found/not found here
Upvotes: 0
Reputation: 150614
Quoted from the MSDN website you linked to:
The first element that matches the conditions defined by the specified predicate, if found; otherwise, the default value for type T.
This describes the return value. Hence, when no match is found, the default
value for type T
is returned, which means null
for reference types, and things such as 0
, false
& co. for value types.
So in your calling code, simply check for this default value, and you're fine :-). What you can not do is just use the value that is being returned, as this e.g. might result in a NullReferenceException
, if you are using a reference type.
Upvotes: 2