Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ Single() Exception for 0 or multiple items

I have some IEnumberable collection of items. I use .Single() to find a specific object in the collection.

I choose to use Single() because there should only ever be one specific item. However, if one doesn't exist, then I need to create it and add it to the collection.

My problem is that Single() throws the same error if there is no item matching the predicate or if there are multiple items. My idea was to put the Single() call inside of a try and catch the exception, add the item, and then continue. However, since both scenarios throw the InvalidOperationException, how can I tell if its due to no items or multiple items?

I know I can use First() but that doesn't enforce the idea that there should be only one (without doing extra work).

I could also use Count() before the Single() call, but that just seems to undermine the point of Single()

like image 431
Justin Self Avatar asked Nov 21 '12 17:11

Justin Self


People also ask

What is the difference between first () and single () extension methods in LINQ?

1. First() returns the first element of a sequence even there is a single element in that sequence. 2. Single() returns the single element of a sequence and that element should be the exactly a single one.

What is single () in C#?

C# Single() MethodGet only a single element of a sequence using the Single() method. Let's say we have a string array with only one element. string[] str = { "one" }; Now, get the element.

Does SingleOrDefault throw exception?

SingleOrDefault() will throw an exception if there is more than one elements in a colection or for the specified condition.

What is single or default in Linq?

SingleOrDefault<TSource>(IEnumerable<TSource>, TSource)Returns the only element of a sequence, or a specified default value if the sequence is empty; this method throws an exception if there is more than one element in the sequence.


3 Answers

What you want is SingleOrDefault()

The "or default" actually means it returns null (for reference types) or whatever the default would be for a non-reference type. You'll need to new-up an object to take its place.

like image 94
Michael Dunlap Avatar answered Sep 17 '22 01:09

Michael Dunlap


I wouldn't recommend using the try/catch in this scenario, because using exceptions to make logical decisions is resource expensive.

I would recommend using SingleOrDefault(), and check if the result is null. If it is. Do your creation.

like image 41
Khan Avatar answered Sep 21 '22 01:09

Khan


SingleOrDefault will throw an exception when there is more than one item in the set. You will have to check for the size beforehand manually.

var singleItem = list.Count() == 1 ? list.Single() : null;

Maybe it's best to just make your own extension function.

like image 42
apoth Avatar answered Sep 18 '22 01:09

apoth