2

The following code loops through resultSet and populates list a of SomeType. The resultSet itself is an anonymous type with two properties

var resultSet = SomeCollection.Select(x => new {
    FirstProp = x,
    SomeMembers = SomeLinkCollection.Where(l => l.SomeId == x.SomeId)
                                    .Select(l => AnotherCollection[l.Id])
});

var result = new List<SomeType>();
foreach (var currentGroup in resultSet) {
    result.Add(new SomeType {
        Prop1 = currentGroup.Item.Id,
        Prop2 = currentGroup.Item.Name,
        Prop3 = currentGroup.SomeMembers.OrderBy(x => x.Name)
    });
}

To remove setting up new Sometype instances I created a mapper class/interface using dynamic type to split the responsibility and use dependency injecton:

public class SomeMapper : ISomeMapper {
    public List<SomeType> Map(dynamic resultSet) {
        return resultSet.Select(new SomeType {
            Prop1 = currentGroup.Item.Id,
            Prop2 = currentGroup.Item.Name,
            Prop3 = ((IEnumerable<AnotherType>)resultSet.SomeMembers)
                                                .OrderBy(x => x.Name)
        });
    }
}

So the code above becomes:

return resultSet.Select(SomeMapper.Map);

Error

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable>' to 'System.Collections.Generic.List'. An explicit conversion exists (are you missing a cast?)

I tried few tricks with explicit cast to SomeType but it fails at run-time

return (List<SomeType>)groupSet.Select(statusGroupMapper.Map);

Unable to cast object of type
'WhereSelectListIterator2[AnotherType,System.Collections.Generic.List1[SomeType]]' to type 'System.Collections.Generic.List`1[SomeType]'.

Castrohenge
  • 8,525
  • 5
  • 39
  • 66
Anupam Yadav
  • 4,353
  • 4
  • 19
  • 20

1 Answers1

3

You need to create a list of the result.

Simply add .ToList() after your expression:

public class SomeMapper : ISomeMapper {
    public List<SomeType> Map(dynamic resultSet) {
        return resultSet.Select(new SomeType {
            Prop1 = currentGroup.Item.Id,
            Prop2 = currentGroup.Item.Name,
            Prop3 = ((IEnumerable<AnotherType>)resultSet.SomeMembers).OrderBy(x => x.Name)
        }).ToList();
    }
}

.Select(...) returns an IEnumerable<T>, not a List<T>, so this is exactly the same type of problem you would have with this method:

public string Name()
{
    return 10; // int
}

You also have a problem when you call it, don't do this:

return (List<SomeType>)groupSet.Select(statusGroupMapper.Map);

just do this:

return statusGroupMapper.Map(groupSet);
Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
  • Thanks for your reply, i tried using .ToList() but the same error still persists Unable to cast object of type 'WhereSelectListIterator2[AnotherType,System.Collections.Generic.List1[SomeType]]' to type 'System.Collections.Generic.List`1[SomeType]'. – Anupam Yadav Jul 17 '13 at 12:49
  • You're still casting, remove the cast. – Lasse V. Karlsen Jul 17 '13 at 12:52
  • removing cast gives me compile time error Error 61 Cannot implicitly convert type 'System.Collections.Generic.IEnumerable>' to 'System.Collections.Generic.List'. An explicit conversion exists (are you missing a cast?) – Anupam Yadav Jul 17 '13 at 12:58
  • You need to call `.ToList()`, as pointed out in the answer. Can't you simply copy my code and see if that works instead of modifying your own? – Lasse V. Karlsen Jul 17 '13 at 13:00
  • I did call .ToList() also i tried pasting your answer but without explicit casting the compile time error (as detailed above) still persists. – Anupam Yadav Jul 17 '13 at 13:17
  • OK, I see why now, you're also munging up the result when calling it. The result is already a list (when it successfully comes out of the method), you don't need a cast or a `Select` here. – Lasse V. Karlsen Jul 17 '13 at 13:25