I'm very confused about this issue and can't understand it.In the Enumerable
Documentation, I read this:
that implement System.开发者_开发知识库Collections.Generic.IEnumerable
and some methods like Select()
return IEnumerable<TSource>
that we can use from other methods like Where()
after using that.for example:
names.Select(name => name).Where(name => name.Length > 3 );
but Enumerable
doesn't inherit from IEnumerable<T>
and IEnumerable<T>
doesn't contain Select()
,Where()
and etc too...
have i wrong ?
or exists any reason for this?The Select(), Where() etc are "extension methods". They need to be defined "elsewhere" as an interface can't supply an implementation of methods.
You can recognize extension methods by the keyword "this" in the argument list. For instance:
public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate
)
can be used as if it's a method on an IEnumerable<TSource>
with one parameter: Func<TSource, bool> predicate
.
Correct.but what about this sentence?
that implement System.Collections.Generic.IEnumerable
According to this sentence,We have to define methods in the IEnumerable<T>
interface and implement in the Enumerable
class by inheritance.is it correct?
why preferred extension methods against inheritance?
IEnumerable came before IEnumerable<T>
, which is a 2.0+ interface.
"why preferred extension methods against inheritance?"
Enumerable is a static class that implements over 50 extension methods to IEnumerable. This lets you use all those extension methods on types that implement IEnumerable without forcing the programmers to implement all those methods for each collection type. If Enumerable were an interface instead of a static class, each collection type (such as List, Dictionary, Set, etc) would have its own implementation of these extension methods.
A way to solve this is by casting the elements to their same type using Cast<T>()
method, which returns and IEnumerable<T>
version of the same elements.
DataTable dt = ...
dt.Rows.Cast<DataRow>().Where()...
Rows
is of type IEnumerable
, and after casting it becomes of type IEnumerable<DataRow>
, which is supported by LINQ extension methods.
I had say you also have a read on this article Iterators, iterator blocks and data pipelines by Jon Skeet for further insights
精彩评论