i have an object that is a:
IQueryable<Foo>
and i want to pass it into a function that expects a:
IQueryable<IFoo>
Foo DOES implements IFoo
why wouldn't this compile? what is the best way to convert to have this work?
Co- and contra- variance were added in the .NET 4 BCL, and do not exist in the .NET 3.5 BCL.
You can work around this limitation in 3.5 by using the Select
operation to cast to your interface type:
IQueryable<Foo> foos = ..;
myFunc(foos.Select(x => (IFoo)x));
Edit (from Reed's comment, below):
IQueryable<Foo> foos = ..;
myFunc(foos.Cast<IFoo>());
In addition to the answer by Stephen Cleary , you could also use the OfType expression:
IQueryable<Foo> foos = GetFoos();
var ifoos = foos.OfType<IFoo>();
I'd imagine the OfType
method may be a bit faster since the expression is filters the collection by type rather than casting.
Anthony Pegram made a good observation/point in the comments. Here's a quick test of OfType<>
vs Cast<>
on a collection of 1,000,000 items:
OfType Test
00:00:00.1034880
00:00:00.0966734
00:00:00.0969874
00:00:00.1318617
00:00:00.0984404
00:00:00.0970098
00:00:00.0981691
00:00:00.0972425
00:00:00.1330730
00:00:00.1239663
total: 00:00:01.0769116
avg: 00:00:00.1076911
Cast Test
00:00:00.0556266
00:00:00.0729768
00:00:00.0512704
00:00:00.0519060
00:00:00.0533288
00:00:00.0752939
00:00:00.0754975
00:00:00.0821554
00:00:00.0536814
00:00:00.0754732
total: 00:00:00.6472100
avg: 00:00:00.0647210
The reason why that doesn't work is because List<Foo>
is a new class being generated and so is List<IFoo>
... so, by the time the compiler is done with them, their will now be 2 totally new and unique classes in your project.
EDIT: A sort-of-solution:
What you can do is this:
var myIFooList = myFooList.Select(item => (IFoo)item).ToList();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.