Question

I'm currently refactoring a project I'm doing at the university I'm attending. Part of this refactoring is to make parts of the project more concise, and use less code. Some times I run several foreach loops and add stuff to a List.

I have the following code-chunk which works as intended

private List<Literal> GetClashingLiterals(ClauseNode other)
{
    List<Literal> clashes = new List<Literal>();
    foreach (Literal literal in literals)
    {
        foreach (Literal otherlit in other.literals)
        {
            if (literal.Name.Equals(otherlit.Name) 
                && !(literal.Sign.Equals(otherlit.Sign)))
            {
                clashes.Add(literal);
            }
        }
    }
    return clashes;
}

I would like to transform this piece of code to a lambda expression. I found this old question here on stackoverflow C# - Populate a list using lambda expressions or LINQ.

I thought it was just what i needed, so I made this lambda-expresison and tested it:

List<Literal> clashes = (List<Literal>)literals
    .Where(lit => other.literals
        .Any(lit2 => lit.Name.Equals(lit2.Name) 
            && !lit.Sign.Equals(lit2.Sign)));

However it doesn't work. I get an InvalidCastException whenever i try to run it. Without the cast, it doesn't compile! So what am i missing?

This is the exception:

Unable to cast object of type 'WhereEnumerableIterator1[Heureka.Model.Literal]' to type 'System.Collections.Generic.List1[Heureka.Model.Literal]'.

Was it helpful?

Solution

As the error says, LINQ methods do not return List<T>. If you need a List<T>, you need to call ToList()

List<Literal> clashes =  literals
    .Where(lit => other.literals
       .Any(lit2 => lit.Name.Equals(lit2.Name) && !lit.Sign.Equals(lit2.Sign)))
    .ToList();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top