Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IEnumerable<type> does not contain a definition of 'Contains'

Tags:

c#

.net

linq

I have 2 classes and 2 IEnumerable lists of those classes:

public class Values
{
    public int Value { get; set; }
    public DateTime SomeDate { get; set; }
}

public class Holidays
{
    public DateTime holiday { get; set; }
}

IEnumerable<Values> values;
IEnumerable<Holidays> holidays;

Next, I am trying to select those 'values' where 'someDate' is not in 'holidays'

var query = values.Where(x=> !holidays.Contains(x.someDate));

However, this gives me the error of IEnumerable<Holidays> does not contain a definition of 'Contains'.

System.Linq is already added in the usings.

I believe this has to do something with the collections, but am not able to figure what.

like image 453
Prashant Kamdar Avatar asked Mar 22 '16 16:03

Prashant Kamdar


People also ask

Which method does not contain definition in Java?

Linq Method does not contain a definition for (Contains)

Does IEnumerable have count?

IEnumerable doesn't have a Count method.

Does not contain a definition for and the best extension method overload?

'Type' does not contain a definition for 'method' and the best extension method overload 'method' has some invalid arguments. This error is produced when the compiler cannot find a class member with the name of the method you have called.

Does not contain definition for and no extension method?

'type' does not contain a definition for 'name' and no accessible extension method 'name' accepting a first argument of type 'type' could be found (are you missing a using directive or an assembly reference?). This error occurs when you try to call a method or access a class member that does not exist.


2 Answers

When you use Contains, the object you're looking for must match the type T of the IEnumerable<T>. Thus, you cannot search IEnumerable<A> for a contained object of type B since there's no implicit way to compare the two.

As mentioned in other answers, use Any and pass in the comparison yourself.

Alternatively, this is also a case where you could use a Select followed by Contains, although this may be less readable in some cases:

var query = values
    .Where(x => !holidays
        .Select(h => h.holiday)
        .Contains(x.someDate));
like image 183
David Avatar answered Oct 12 '22 17:10

David


As an alternative to what everyone else has suggested already:

var holidayDates = new HashSet<DateTime>(holidays.Select(h => h.holiday));
var query = values.Where(x => !holidayDates.Contains(x.someDate));

In particular, if you have a lot of holidays, this change will make the per-value check much more efficient.

like image 21
Jon Skeet Avatar answered Oct 12 '22 17:10

Jon Skeet