tags:

views:

215

answers:

2

I am playing about with the IQueryProvider.Execute command and am passing in an expression which is part of my expression tree project. This command gives me back an object which can be either an OrderedEnumerable or a GroupedEnumerable depending on the original expression. A GroupBy expression creates the GroupedEnumerable object. The following code also creates a GroupedEnumerable object which will show you an example of the problem I am having.

List<int> numbers = new List<int> { 1, 7, 16, 23, 41, 66 };
object grouped = numbers.GroupBy(n => n % 2 == 0);

When “grouped” is an object (of GroupedEnumerable) I cannot cast it to any other type that will allow me to call “GetEnumerator” on it. I am also unable to cast it to anything that will allow me to use it with a “foreach” command for example. If I change the code to use a “var” (as shown below), grouped is now of type OrderedEnumerable. I can get the enumerator and use it in a foreach command.

List<int> numbers = new List<int> { 1, 7, 16, 23, 41, 66 };
var grouped = numbers.GroupBy(n => n % 2 == 0);

Going back to my expression tree project, the IQueryProvider.Execute command returns an object but I need to be able to cast the object to an OrderedEnumerable when the object is a GroupedEnumerable. All the casts I have tried show an error along the lines of “Unable to cast object of type 'System.Linq.GroupedEnumerable`3 to type .....”. Anyone able to tell me how to cast the object to something more useful?

+1  A: 

Just cast the object to IEnumerable<T>. The enumerable implementation shouldn't matter to you.

JSBangs
+4  A: 

The result of your GroupBy call will be IEnumerable<IGrouping<bool, int>>. You can see this if you hover over the word var in your second code example. Cast it to this type and it will work correctly.

List<int> numbers = new List<int> { 1, 7, 16, 23, 41, 66 };
object grouped = numbers.GroupBy(n => n % 2 == 0);

IEnumerable<IGrouping<bool, int>> foo = 
    (IEnumerable<IGrouping<bool, int>>)grouped;

Edit

After your comments above, if the output of your call is GroupedEnumerable<MyEntityItem,int?,MyEntityItem>, then you can cast it to IEnumerable<IGrouping<int?, MyEntityItem>>.

Adam Robinson
When I try to cast in this way it won't compile as it gives the error "IEnumerable<T> requires 1 type argument.
Retrocoder
@Retrocoder: Sorry, I've edited the answer. Give that a shot.
Adam Robinson
Hi, that worked fine, so I now have the object cast to a GroupedEnumerable<MyEntityItem,int?,MyEntityItem> which is what I wanted, many thanks for that. You may be able to help me with a second question. This code is in the “IEnumerator<T> GetEnumerator()” method of a class that derives from IOrderedQueryable<T>. I find that I can’t return the Enumerator of the “GroupedEnumerable<MyEntityItem,int?,MyEntityItem>” as the cast throws an error.
Retrocoder
The error is:Unable to cast object of type 'System.Linq.GroupedEnumerable`3[MyEntityItem,System.Nullable`1[System.Int32],MyEntityItem]' to type 'System.Collections.Generic.IEnumerable`1[MyEntityItem]'.Is it possible to do a cast or is this never going to work?
Retrocoder