Home Random Page


CATEGORIES:

BiologyChemistryConstructionCultureEcologyEconomyElectronicsFinanceGeographyHistoryInformaticsLawMathematicsMechanicsMedicineOtherPedagogyPhilosophyPhysicsPolicyPsychologySociologySportTourism






Nbsp;   All Arrays Implicitly Implement IEnumerable, ICollection, and IList

There are many methods that operate on various collection objects because the methods are de- clared with parameters such as IEnumerable, ICollection, and IList. It is possible to pass arrays to these methods because System.Array also implements these three interfaces. System.Array implements these non-generic interfaces because they treat all elements as System.Object. How- ever, it would be nice to have System.Array implement the generic equivalent of these interfaces, providing better compile-time type safety as well as better performance.

The CLR team didn’t want System.Array to implement IEnumerable<T>, ICollection<T>, and IList<T>, though, because of issues related to multi-dimensional arrays and non-zero–based arrays. Defining these interfaces on System.Array would have enabled these interfaces for all array types. Instead, the CLR performs a little trick: when a single-dimensional, zero–lower bound array type is created, the CLR automatically makes the array type implement IEnumerable<T>, ICollection<T>, and IList<T> (where T is the array’s element type) and also implements the three interfaces for all of the array type’s base types as long as they are reference types. The following hierarchy diagram helps make this clear.

 

Object

Array (non­generic IEnumerable, ICollection, IList)

Object[] (IEnumerable, ICollection, IList of Object) String[] (IEnumerable, ICollection, IList of String) Stream[] (IEnumerable, ICollection, IList of Stream)

FileStream[] (IEnumerable, ICollection, IList of FileStream)

.

. (other arrays of reference types)

.

 

So, for example, if you have the following line of code:

 

FileStream[] fsArray;

 

then when the CLR creates the FileStream[] type, it will cause this type to automatically implement the IEnumerable<FileStream>, ICollection<FileStream>, and IList<FileStream> inter- faces. Furthermore, the FileStream[] type will also implement the interfaces for the base types: IEnumerable<Stream>, IEnumerable<Object>, ICollection<Stream>, ICollection<Object>, IList<Stream>, and IList<Object>. Because all of these interfaces are automatically implemented by the CLR, the fsArray variable could be used wherever any of these interfaces exist. For example, the fsArray variable could be passed to methods that have any of the following prototypes.

 

void M1(IList<FileStream> fsList) { … }

void M2(ICollection<Stream> sCollection) { … } void M3(IEnumerable<Object> oEnumerable) { … }


Note that if the array contains value type elements, the array type will not implement the inter- faces for the element’s base types. For example, if you have the following line of code:

 

DateTime[] dtArray; // An array of value types

 

then the DateTime[] type will implement IEnumerable<DateTime>, ICollection<DateTime>, and IList<DateTime> only; it will not implement versions of these interfaces that are generic over System.ValueType or System.Object. This means that the dtArray variable cannot be passed as an argument to the M3 method shown earlier. The reason for this is because arrays of value types



are laid out in memory differently than arrays of reference types. Array memory layout was discussed earlier in this chapter.

 

 


Date: 2016-03-03; view: 646


<== previous page | next page ==>
Nbsp;   Casting Arrays | Nbsp;   Array Internals
doclecture.net - lectures - 2014-2024 year. Copyright infringement or personal data (0.008 sec.)