It's nothing to do with GroupBy - it's because IList<T> is invariant. If you could cast a List<MyClass> to IList<IMyClass> then the caller could then add an instance of a type which implemented IMyClass but wasn't a MyClass. (I usually think of this in terms of real world objects: a bunch of bananas isn't a fruit bowl: you can add an apple to a fruit bowl, but not to a bunch of bananas.)
The simplest way would be to manually specify the type in the Select clause:
public IList<IMyClass> Foo()
{
IList<IMyClass> foo = SomeQuery();
var result = foo.GroupBy(x => x.bar)
.Select<IGrouping<IMyClass, Bar>>, IMyClass>(x => new MyClass())
.ToList();
return result;
}
This means result will actually be a List<IMyClass>. I don't know the type of item within foo which makes it tricky to give it in more detail - given your comment, I'll assume that that's IMyClass, and that x.bar is of type Bar.
Another alternative (which would be more useful if you wanted to use a query expression for the group/select part) would be to use Cast:
public IList<IMyClass> Foo()
{
IList<IMyClass> foo = SomeQuery();
var result = foo.GroupBy(x => x.bar)
.Select(x => new MyClass())
.Cast<IMyClass>()
.ToList();
return result;
}
Or perform the cast within the Select lambda expression itself:
public IList<IMyClass> Foo()
{
IList<IMyClass> foo = SomeQuery();
var result = foo.GroupBy(x => x.bar)
.Select(x => (IMyClass) new MyClass())
.ToList();
return result;
}
EDIT: Apologies for the Select failure. It's somewhat annoying that you have to specify both the source and the result, but there's no easy way of fixing that :( Given the ugliness involved, you may well be best off with Cast.