Проблема с небезопасным по типу перечислением

проблема интерфейса lenumerator b b

До появления.NET 2.0 модель перечисления поддерживалась интерфейсами LEnumerable И LEnumerator. Проблема интерфейса LEnumerator Состоит в том, что его свойство Current Возвращает только ссылку типа Object, И для правильного ее использования необходимо приведение к действительному типу объекта. Помимо незащищенности в отношении типа, такое положение дел порождает проблемы производительности, когда коллекции содержат типы-значе — ния, а само приведение невозможно без некоторых затрат. Типы-значения при передаче в качестве обьектных ссылок должны упаковываться, т. е. в области сборщика мусора должна выделяться память для объекта, который будет содержать значение, значение должно быть скопировано из стека в обьект, и вы получаете в качестве обьектной ссылки ссылку на эту память. Далее обычно вы, получив доступ к элементу коллекции через свойство LEnumerator .Current, Приводите ссылку обратно к соответствующему типу. Если это тип-значение, то для приведения к нужному типу Объектная ссылка должна быть распакована и скопирована в переменную, размещенную на стеке. После этого выделенный ранее объект становится доступен для сборки в качестве мусора, что увеличивает нагрузку на сборщик. Все это связано с издержками производительности, которых следует избегать. Учитывая вышесказанное, всегда отдавайте предпочтение обобщенным типам коллекций и интерфейсов, чтобы избежать проблем, возникающих при непосредственной работе с коллекцией конкретного типа. Операция Foreach Избегает их, обращаясь к свойству Current И методу MoveNext Непосредственно объекта-перечислителя, а не через интерфейс LEnumerator. Это позволяет перечислителю возвращать действительный тип элемента, а не бессмысленную объектную ссылку. Кроме того, операция Foreach Может работать непосредственно с действительным типом элементов коллекции, обходя, таким образом, упаковку и распаковку типов-значений, если последние корректно реализуют свои перечислители.

Вы можете спросить, для чего нужны два отдельных интерфейса. Почему не определить всего один интерфейс, реализуемый самой коллекцией, который непосредственно поддерживает итерацию по коллекции? Ответ состоит в том, что вам может потребоваться поддерживать не одну форму итерации по коллекции, поэтому выделение логики итерации в отдельный объект позволяет вам при необходимости подключать дополнительные формы итерации.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *