Why can't I use LINQ methods on my class implementing IEnumerable?
-
17-04-2021 - |
Question
I have to complete a project but I have a simple problem
I have a class defined in this way
using System;
using System.Collections;
using System.Collections.Generic;
..
public class GroupId: XmlDataTransferObject, IEnumerable
{
private IList _groupId;
private string _nameId;
public GroupId() : this("GroupId", "Id")
{
}
public GroupId(string rootName, string nomeId) : base(rootName)
{
_groupId = new ArrayList();
_nomeId = nomeId;
}
public override bool IsNull
{
get { return _groupId.Count == 0; }
}
public int Count
{
get { return _groupId.Count; }
}
public int Add(Intero i)
{
return _groupId.Add(i);
}
public Intero this[int index]
{
get { return (Intero)_groupId[index]; }
set { _groupId[index] = value; }
}
...
public IEnumerator GetEnumerator()
{
return _groupId.GetEnumerator();
}
}
}
and I need to find the intersection between an instance of two GroupId objects.
Why can't I see in the available methods the Linq Intersect even if I have declared the statement:
Using System.Linq
...
var x = _groupId1.Intersect(_groupId2);
...
Error 1 '....GroupId' does not contain a definition for 'Intersect' and no extension method 'Intersect' accepting a first argument of type '...GroupId' could be found (are you missing a using directive or an assembly reference?)
Solution
Your GroupId
class only implements the non-generic IEnumerable
class - you should implement IEnumerable<T>
if you want to use the LINQ extension methods. (It'll generally be a better experience anyway.)
Note that that will also be easier if you use a generic IList<T>
instead of the non-generic IList
- basically try to avoid the non-generic collections entirely in new code, if at all possible.
You could use Cast
to convert your IEnumerable
to IEnumerable<T>
like this:
var x = _groupId1.Cast<Intero>().Intersect(_groupId2.Cast<Intero>());
... but it would be much nicer to just make your class implement IEnumerable<Intero>
.
OTHER TIPS
Because your _groupId1
is declared as an IList
, which is only an IEnumerable
.
You need a generic enumerable (IEnumerable<T>
) for nearly all the linq extension methods. Your choice is change the declaration, or use one of the Cast<T>
or OfType<T>
extensions.
try _groupId1.OfType<Intero>().Intersect(...)
or declaring it as IList<Intero>