КАТЕГОРИИ:
АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника
|
Все массивы неявно реализуют /Enumerable, /Collection и IListМногие методы работают с разными наборами объектов только потому, что эти методы объявлены с такими параметрами, как IEnumerable, ICollection и IList. В эти методы можно передавать массивы, так как SystemArray также реализует эти три интерфейса. SystemArray реализует эти три необобщенных интерфейса, потому что они обращаются со всеми элементами как с System.Object. Однако было бы неплохо, если бы SystemArray реализовала обобщенные эквиваленты этих интерфейсов, обеспечивая лучший контроль типов во время компиляции и производительность. Команда разработчиков CLR не хотела, чтобы SystemArray реализовывала IEnu-merable<T>,ICollection<T> nIList<T>, из-за проблем, возникающих с многомерными массивами и массивами, в которых нумерация не начинается с нуля. Определив эти интерфейсы, пришлось обеспечить поддержку всех типов массивов. Вместо этого разработчики CLR пошли на хитрость: при создании типа одномерного массива с индексацией с нуля CLR автоматически реализует в типе ШпитегаЫе-<Т>, ICollection<T> и IList<T> (где Т — тип элементов массива), а также три интерфейса для всех базовых типов типа массива, при условии, что все они — ссылочные типы. Следующая иерархия иллюстрирует эту ситуацию. Object Array (необобщенные 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)
(другие массивы ссылочного типа)
Итак, при наличии следующей строчки кода: FileStream[] fsArray; при создании типа FileStreamfJ CLR автоматически реализует в нем интерфейсы IEnumerable<FileStream>,ICollection<FileStream> и IList<FileStream>. Кроме того, тип FileStream[] будет реализовывать интерфейсы базовых классов IEnumerable<Stream>, IEnumerable<Object>, ICollection<Stream>, ICollection<Object>, IIJst<Stream> и IIJsK Object>. Так как все эти интерфейсы реализуются средой CLR автоматически, переменная fsArray может применяться во всех случаях использования этих интерфейсов. Например, переменную fsArray можно передавать в методы с таким прототипами: void M1(IList<FileStream> fsList) { ... } void M2(ICollection<Stream> sCollection) { ... } void M3(IEnumerable<0bject> oEnumerable) { ... } Заметьте: если массив содержит элементы значимого типа, тип массива не будет реализовывать интерфейсы базовых классов элемента. Например, при наличии следующей строчки кода: DateTime[] dtArray; // Массив с элементами значимого типа. тип DateTime[] будет реализовывать только интерфейсы IEnumerable<DateTime>, ICollection<DateTime> и IList<DateTime>, но не версии этих интерфейсов, общие для SystemValueType или System.Object. Это означает, что переменную dtArray нельзя передавать в качестве аргумента в показанный ранее метод МЗ, потому что массивы значимых типов размещаются в памяти иначе, чем массивы ссылочных типов — об этом говорилось в этой главе ранее.
|