views:

132

answers:

1

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; }
    }

}
+2  A: 

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.

Jon Skeet
May also need the *OrDefault() variants if it's valid for a record to not exist.
Garry Shutler
Yes, I'll add that to the answer.
Jon Skeet
Had also forgotten the overload taking a predicate - even simpler :)
Jon Skeet
Didn't know about the overload. Makes it just that little easier to read.
borisCallens