Why can an array be queried using linq?
Problem cause
This is almost a topic that does not need to be discussed at all, because linq (here specifically, linq to objects) is originally for the set type, the array type can be used as a collection type. But I still want to write it down. This problem comes from a friend in the QQ Group's question:. Net arrays all inherit the Array class implicitly. This class is an abstract class and implements the IEnumerable, ICollection, and IList interfaces. However, the linq method is intended for implementing IEnumerable <T> generic interfaces. The Array class does not implement these generic interfaces. Why can I use these methods?
The essence of linq to objects is to implement set query through extension methods. These extension methods are defined in an Enumerable static class. The first parameter of all extension methods in the Enumerable class is of the IEnumerable <T> type, indicating that it can be called through the IEnumerable <T> type.
Analysis of array types
1. All Array types are implicitly derived from Array
When we define a FileStream [] array, CLR will create a FileStream [] type for the current AppDomain, which is derived fromArray. Therefore, the array is a reference type and memory space is allocated in the heap. The Array class is an abstract class that defines many common instance methods and static methods for all Array types. For example, the Length attribute and CopyTo method are common.
2. All array types implicitly implement the IEnumerable <T> interface.
As mentioned above, this is a matter of course. In order to improve development efficiency, the array type should be able to use linq for query. However, because the Array can be a multi-dimensional Array or a non-zero-base Array, the Array class does not implement the IEnumerable <T>, ICollection <T>, and IList <T> generic interfaces, but only non-generic versions are implemented. In fact, the CLR will automaticallyOne-dimensional array typeImplement these generic interfaces (specify the specific type of T-type parameters) and implement them for their parent class. For example, if we define a FileStream [] array type, the CLR will create the following hierarchical structure for us:
Due to the implicit implementation of CLR, we can apply the one-dimensional array type to the places where the IEnumerable <T> generic interface is required.
As mentioned above, we can pass the FileStream [] type object to the following method:
Void F1 (IEnumerable <object> oEnumerable );
Void F2 (ICollection <Stream> sCollection );
Void F3 (IList <FileStream> fList );
This is for the reference type. If it is a value type, it is not necessary to implement these interfaces with its base class. For example, for the DateTimel type (the base class includes ValueType and Object), The DateTime [] array type cannot be passed to the F1 method above, this is because the memory layout of the value type array is different from that of the reference type array.