Типизированный Iterator
От: V.Petrovski Беларусь  
Дата: 01.03.05 08:33
Оценка:
Читая статью "Элегантный код на основе анонимных методов, итераторов и частичных классов" моё внимание привлекла фраза

C# 1.0 позволяет реализовать шаблон итератора для каждого цикла без IEnumerator или IEnumerable, хотя о такой возможности большинство разработчиков не знает. Тогда компилятор будет вызывать строго типизированную версию, не прибегая к приведению типов и упаковке. Так что даже в версии 1.0 можно избежать снижения производительности.


Я взглянул в спецификацию языка и нашел описание этой возможности

To iterate through a collection, the collection must meet specific requirements. For example, in the following foreach statement:

foreach (ItemType item in myCollection)


myCollection must meet the following requirements:

The collection type:
    1. Must be one of the types: interface, class, or struct.
    2. Must include an instance method named GetEnumerator that returns a type, for example, Enumerator (explained below).
The type Enumerator (a class or struct) must contain:
    1. A property named Current that returns ItemType or a type that can be converted to it. The property accessor returns the current element of the collection.
    2. A bool method, named MoveNext, that increments the item counter and returns true if there are more items in the collection.


Исходя из этого описывая коллекцию вот таким вот образом мы делаем строго типизированную версию итератора.

using System;
using System.Collections;

namespace TypedEnumerator
{
    public class MyCollection/* : IEnumerable */
    {
        public int[] items;

        public MyCollection(int capacity) 
        {
            items = new int[capacity];
        }

        public MyEnumerator GetEnumerator() 
        {
            return new MyEnumerator(this.items);
        }
/*
        IEnumerator IEnumerable.GetEnumerator() 
        {
            return GetEnumerator();
        }
*/
        public class MyEnumerator/* : IEnumerator */
        {
            int i;
            int[] items;
            private int length;

            public DataObjCollection2Enumerator(int[] items) 
            {
                this.items = items;
                this.i = -1;
                this.length = items.Length;
            }

            public bool MoveNext() 
            {
                i++;
                return i < length;
            }

            public void Reset()
            {
                i = -1;
            }

            public int Current 
            {
                get 
                {
                    return items[i];
                }
            }
            /*
            object IEnumerator.Current 
            {
                get 
                {
                    return Current;
                }
            }
            */
        }
    }
}

Раскометировав все строки в этом примере мы добавим реализацию интерфейсов IEnumerable и IEnumerator но на производительности кода это никак не скажеться.

Хотя в спецификации C#1.0 написано, что такая колекция может использоваться только в языке C#, это ЛОЖЬ.
Такую колекцию можно использовать и в VB.NET.

Вот реpультаты пробега по колекциям в 1 миллион элементов типа Int32, при помощи их итераторов
на C#

int[]. Duration : 0,0029 sec
ArrayList. Duration : 0,0418 sec
MyCollectionBase. Duration : 0,0379 sec
MyCollection. Duration : 0,0144 sec

на VB.NET

int[]. Duration : 0,0029 sec
ArrayList. Duration : 0,0821 sec
MyCollectionBase. Duration : 0,0768 sec
MyCollection. Duration : 0,0148 sec


Как видите int[] и MyCollection работаю практически одинаково на двух языках, что не скажешь о ArraList и CollectionBase.
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.