Marcom
Marcom

Reputation: 4741

Do a linq query on an object array?

I have a collection of type objects which I know they are type Employee. I'd like to perform some linq operations on them using the employee some thing similar to this:

 var options = (from e in m_Employees  
                      select (e as Employee).DepartmentCode).Distinct();

But the as employee is not surprisingly giving an error. is there a way around it?

Changing the collection is not really an options since I,m maintaining the code and I want to avoid big changes.

Upvotes: 2

Views: 7382

Answers (5)

Jon Skeet
Jon Skeet

Reputation: 1500525

Rather than using as Employee it would be better to make the compiler basically insert a call to Cast<T> using an explicitly typed range variable:

var options = (from Employee e in m_Employees
               select e.DepartmentCode).Distinct();

Or alternatively and equivalently:

var options = m_Employees.Cast<Employee>()
                         .Select(e => e.DepartmentCode)
                         .Disinct();

However, I still wouldn't have expected your original code to fail, if the array really does only include Employee references... If you were getting a NullReferenceException then either one of the values was null, or it was a non-null reference to a non-Employee object. These will both still give you an error with the above code, but you'll be able to see which one based on whether you still get a NullReferenceException or an InvalidCastException.

In general you should only use as when you're going to use the result conditionally. If you're sure that every value is really of the right type, you should use a cast instead - so that if you're wrong, you'll get the code blowing up with an exception instead of propagating a null reference to the rest of the code, where it could cause harm later on and make it hard to spot the source of the error.

If you were getting a compile-time error then there are a number of possible causes, based on what exception you were seeing.

EDIT: Okay, so it was an IEnumerable causing a compile-time error... Cast<T>() and OfType<T>() are both extension methods on just IEnumerable instead of on IEnumerable<T>.

Upvotes: 6

mgronber
mgronber

Reputation: 3419

You could try this:

var options = m_Employees
        .Cast<Employee>()
        .Select(item => item.DepartmentCode)
        .Distinct();

Upvotes: 0

Albin Sunnanbo
Albin Sunnanbo

Reputation: 47038

You can use either

from e in m_Employees.Cast<Employee>()
    select e.DepartmentCode

or

from e in m_Employees.OfType<Employee>()
    select e.DepartmentCode

Cast thows an error if you can not cast each item to Employee, but OfType will filter out those objects not matching the type.

Upvotes: 9

Daniel Hilgarth
Daniel Hilgarth

Reputation: 174309

Use this:

var options = (from e in m_Employees.Cast<Employee>()
               select e.DepartmentCode).Distinct();

The important part is the Cast<Employee>. My answer assumes that m_Employees is an IEnumerable like ArrayList instead of an IEnumerable<Employee> like List<Employee>.

Upvotes: 0

Ralph Shillington
Ralph Shillington

Reputation: 21098

One option would be:

(from e in m_Employees
let x = e as Employee
select x.DepartmentCode).Distinct();

Upvotes: 0

Related Questions