How to get a custom object out of a generic List with LINQ?
-
03-07-2019 - |
Question
Why do I get the following error in the following code?
I thought if I put custom objects in a generic List of its type then IEnumerable would be taken care of? What else do I need to do to this List to use LINQ on it?
Cannot implicitly convert type 'System.Collections.Generic.IEnumerable
<TestLinq23.Customer>
' to 'TestLinq23.Customer'
using System;
using System.Collections.Generic;
using System.Linq;
namespace TestLinq23
{
class Program
{
static void Main(string[] args)
{
List<Customer> customerSet = new List<Customer>();
customerSet.Add(new Customer { ID = 1, FirstName = "Jim", LastName = "Smith" });
customerSet.Add(new Customer { ID = 2, FirstName = "Joe", LastName = "Douglas" });
customerSet.Add(new Customer { ID = 3, FirstName = "Jane", LastName = "Anders" });
Customer customerWithIndex = customerSet[1];
Console.WriteLine("Customer last name gotten with index: {0}", customerWithIndex.LastName);
Customer customerWithLinq = from c in customerSet
where c.FirstName == "Joe"
select c;
Console.WriteLine(customerWithLinq.LastName);
Console.ReadLine();
}
}
public class Customer
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
Solution
You need to add a call to Single()
- otherwise it's returning a sequence of customers.
At the same time, there's no real need to use a query expression here. It'll be simpler to use dot notation:
Customer customerWithLinq = customerSet.Where(c => c.FirstName == "Joe")
.Single();
In fact, you can make it even simpler, because there's an overload of Single()
to take a predicate:
Customer customerWithLinq = customerSet.Single(c => c.FirstName == "Joe")
Is it an error condition if there isn't exactly one match? If not, you might want to use First()
instead of Single()
.
EDIT: As pointed out by Garry, if there may be no results you might want SingleOrDefault()
or FirstOrDefault()
- both of these will return null
if no entries match.