Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.81/16: Рейтинг темы: голосов - 16, средняя оценка - 4.81
0 / 0 / 0
Регистрация: 16.05.2014
Сообщений: 6

Разница в реализации GetEnumerator()

16.05.2014, 01:03. Показов 3432. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Объясните, плз, разницу в реализации GetEnumerator() в коде. Не могу понять почему так, а, к примеру, не наоборот.
C#
1
2
3
4
5
6
7
8
9
        public IEnumerator<T> GetEnumerator()
        {
              return ((IEnumerable<T>) elements).GetEnumerator();
        }
 
        IEnumerator IEnumerable.GetEnumerator()
        {
           return (this as IEnumerable<T>).GetEnumerator();
        }
Полный код под спойлером:
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
class UserCollection<T> : ICollection<T>
    {
        T[] elements = new T[0];
 
        public void Add(T item)
        {
            var newArray = new T[elements.Length + 1];
            elements.CopyTo(newArray, 0);
            newArray[newArray.Length - 1] = item;
            elements = newArray;
        }
 
        public void Clear()
        {
            elements = new T[0];
        }
 
        public bool Contains(T item)
        {
            foreach (var element in elements)
            {
                if (element.Equals(item))
                    return true;
            }
 
            return false; 
        }
 
        public void CopyTo(T[] array, int arrayIndex)
        {
            elements.CopyTo(array, arrayIndex);
        }
 
        public int Count
        {
            get { return elements.Length; }
        }
 
        public bool IsReadOnly
        {
            get { return false; }
        }
 
        public bool Remove(T item)
        {
            throw new NotImplementedException();
        }
 
        public IEnumerator<T> GetEnumerator()
        {
              return ((IEnumerable<T>) elements).GetEnumerator();
        }
 
        IEnumerator IEnumerable.GetEnumerator()
        {
           return (this as IEnumerable<T>).GetEnumerator();
        }
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.05.2014, 01:03
Ответы с готовыми решениями:

Разница реализации постфиксного и префиксного инкрементов
using System; class MainClass { public static void Main(string args) { int x = 0; while (x &lt; 10) { ...

Прерывание GetEnumerator
При запуске программы видно что перечисляется лишь первый элемент. По задумке он должен рекурсивно вызывать этот метод у поддеревьев...

Реализация GetEnumerator()
Здравствуйте, форумчане, помогите пожалуйста с решением задачи. Имеется такой код: class MyClass { int...

16
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
16.05.2014, 01:08
zubr_7,
можно проще:
C#
1
2
3
4
5
6
7
8
9
public IEnumerator<T> GetEnumerator()
{
return elements.GetEnumerator();
}
 
IEnumerator IEnumerable.GetEnumerator()
{
return (this as IEnumerable<T>).GetEnumerator();
}
а так он делает, потому что ICollection реализует IEnumerable и IEnumerable<T>, обобщенный и необобщенный интерфес. Для обобщенного случая вы пишете свой код, а для необобщенного он просто ссылается на обобщенный случай. То есть второй метод тупо вызывает первый, а вот первый вы уже реализуете как-то.
0
9 / 9 / 8
Регистрация: 22.04.2013
Сообщений: 52
16.05.2014, 09:04
проверял кто в IL-code эти записи одно и то же
C#
1
2
3
4
public IEnumerator<T> GetEnumerator()
{
 return ((IEnumerable<T>) elements).GetEnumerator();
}
и
C#
1
2
3
4
public IEnumerator<T> GetEnumerator()
{
return elements.GetEnumerator();
}
или нет?
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
16.05.2014, 09:36
Barii, ну аомотри сам, ildasm со студией же поставляется
0
 Аватар для Spawn
995 / 893 / 354
Регистрация: 24.03.2014
Сообщений: 2,381
Записей в блоге: 2
16.05.2014, 09:52
Во втором случае лишний box получается...

Не по теме:

что вряд ли критично :)

0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
16.05.2014, 13:14
Можно еще проще:
C#
1
2
3
4
5
6
7
8
9
public IEnumerator<T> GetEnumerator()
{
   return elements.GetEnumerator();
}
 
IEnumerator IEnumerable.GetEnumerator()
{
   return GetEnumerator();
}
А так — все одно и то же.
1
0 / 0 / 0
Регистрация: 16.05.2014
Сообщений: 6
16.05.2014, 15:56  [ТС]
Цитата Сообщение от Psilon Посмотреть сообщение
Для обобщенного случая вы пишете свой код, а для необобщенного он просто ссылается на обобщенный случай
Понял. Спасибо. Был невнимателен.
Цитата Сообщение от Spawn Посмотреть сообщение
Во втором случае лишний box получается...
или может лишний upcast?
Цитата Сообщение от kolorotur Посмотреть сообщение
Можно еще проще:
C#
1
2
3
4
public IEnumerator<T> GetEnumerator()
{
     return elements.GetEnumerator();
}
Ругается, что не может сделать неявный каст IEnumerator в IEnumerator<T>. И я вот тоже не понимаю, почему не может?
0
 Аватар для Spawn
995 / 893 / 354
Регистрация: 24.03.2014
Сообщений: 2,381
Записей в блоге: 2
16.05.2014, 16:01
Цитата Сообщение от zubr_7 Посмотреть сообщение
или может лишний upcast?
Нет, именно лишний box.
Цитата Сообщение от zubr_7 Посмотреть сообщение
И я вот тоже не понимаю, почему не может?
IEnumerator<T> "наследует" IEnumerator, но не наоборот...
0
0 / 0 / 0
Регистрация: 16.05.2014
Сообщений: 6
16.05.2014, 16:31  [ТС]
Цитата Сообщение от Spawn Посмотреть сообщение
Нет, именно лишний box.
Второй метод "IEnumerable.GetEnumerator()" вызывается при использовании foreach.
"this as IEnumerable<T>" - идёт приведение текущего экземпляра класса UserCollection<T> к интерфейсу IEnumerable<T>.
Я правильно рассуждаю?
Класс UserCollection<T> реализует ICollection<T>, который, в свою очередь, наследован от IEnumerable<T>, IEnumerable. А upcast это приведение к базовому типу. АААА! хмммммм К чему надо привести экземпляр UserCollection<T> чтоб был upcast?
0
 Аватар для Spawn
995 / 893 / 354
Регистрация: 24.03.2014
Сообщений: 2,381
Записей в блоге: 2
16.05.2014, 16:34
Цитата Сообщение от zubr_7 Посмотреть сообщение
К чему надо привести UserCollection<T> чтоб был upcast?
к Object приведите
0
0 / 0 / 0
Регистрация: 16.05.2014
Сообщений: 6
16.05.2014, 16:36  [ТС]
Цитата Сообщение от Spawn Посмотреть сообщение
к Object приведите
про него я подумал. Но почему приведение к интерфейсу IEnumerable<T> не считается upcastом?
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
16.05.2014, 19:30
zubr_7, приведение интерфейсов работает абсолютно по-другому, нежели поведение классов. Так что не ищите тут аналогий с апкастом и пр. Ну и принцип Лисков.

при вызове foreach вообще не происходит ничего особого. Пример:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
    public class MyEnumerator
    {
        private bool move = false;
        public bool MoveNext()
        {
            return move = !move;
        }
 
        public int Current
        {
            get
            {
                return 15;
            }
        }
    }
 
    class Test
    {
        public MyEnumerator GetEnumerator()
        {
            return new MyEnumerator();
        }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            var test = new Test();
            foreach (var v in test)
            {
                Console.WriteLine(v);
            }
        }
    }ass Test
    {
        public MyEnumerator<int> GetEnumerator()
        {
            return new MyEnumerator<int>();
        }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            var test = new Test();
            foreach (var v in test)
            {
                Console.WriteLine(v);
            }
        }
    }
тут вообще нет ни 1 интерфейса Но все работает
0
0 / 0 / 0
Регистрация: 16.05.2014
Сообщений: 6
16.05.2014, 23:32  [ТС]
Цитата Сообщение от Psilon Посмотреть сообщение
тут вообще нет ни 1 интерфейса Но все работает
мой уровень чуть-чуть выше понимания этой строчки

Уважамый, Spawn! Под "box" вы имели в виду boxing ? Boxing - преобразование типа значений к ссылочному типу. Upcast - приведение к базовому типу.
"this as IEnumerable<T>" - это разве не приведение к базовому типу?
C#
1
2
3
4
IEnumerator IEnumerable.GetEnumerator()
        {
           return (this as IEnumerable<T>).GetEnumerator();
        }
Просто это азы. И очень хочется разобраться во всём!
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
17.05.2014, 00:05
zubr_7, еще раз: с точки зрения среды базовый класс - это одно, а определяемые интерфейсы - совершенно другое.

И при чем тут вообще апкаст?

Добавлено через 44 секунды
zubr_7, так криво вставилось почему-то
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class MyEnumerator
    {
        private bool move = false;
        public bool MoveNext()
        {
            return move = !move;
        }
 
        public int Current
        {
            get
            {
                return 15;
            }
        }
    }
 
    class Test
    {
        public MyEnumerator GetEnumerator()
        {
            return new MyEnumerator();
        }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            var test = new Test();
            foreach (var v in test)
            {
                Console.WriteLine(v);
            }
        }
    }
а вообще IEnumerable<T> "наследует" IEnumerable, поэтому по ссылке IEnumerable можно передавать IEnumerable<T>, но не наоборот.
0
0 / 0 / 0
Регистрация: 16.05.2014
Сообщений: 6
17.05.2014, 22:16  [ТС]
Цитата Сообщение от Psilon Посмотреть сообщение
zubr_7, еще раз: с точки зрения среды базовый класс - это одно, а определяемые интерфейсы - совершенно другое.
разве интерфейс это не аналог абстрактного класса, в котором запрещена реализация?
из моего примера
class UserCollection<T> : ICollection<T>
interface ICollection<T> : IEnumerable<T>, IEnumerable
я до сих пор не могу понять. Почему приведение экземпляра класса UserCollection<T> к IEnumerable<T> вы все называете (соглашаетесь) boxом (boxing, да?), а не upcastом?
0
 Аватар для Spawn
995 / 893 / 354
Регистрация: 24.03.2014
Сообщений: 2,381
Записей в блоге: 2
17.05.2014, 23:16
Почитайте вот эту статейку. Интерфейс это не класс, как ни крутите.
0
0 / 0 / 0
Регистрация: 26.02.2014
Сообщений: 5
17.05.2014, 23:37
C#
1
2
3
4
public IEnumerator<T> GetEnumerator()
        {
              return ((IEnumerable<T>) elements).GetEnumerator();
        }
elements - ссылочный тип. О каких box'ах идет речь?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
17.05.2014, 23:37
Помогаю со студенческими работами здесь

IEnumerable Различие в реализациях GetEnumerator
Для чего при реализации в классе интерфейса IEnumerable&lt;T&gt; реализуют 2 метода GetEnumerator? public IEnumerator&lt;T&gt; GetEnumerator()...

Зачем нужен IEnumerator IEnumerable.GetEnumerator()?
Здесь дан пример. Рассмотрим его часть: public class People : IEnumerable { private Person _people; public People(Person...

Реализация IEnumerable<T>: GetEnumerator не имеет соответствующего возвращаемого типа
Здравствуйте. Помогите пожалуйста разобраться с реализацией IEnumerable&lt;T&gt;. public class Group : IEnumerable&lt;Student&gt; { ...

Ошибка при десериализации JSON: отсутствует открытое определение экземпляра для GetEnumerator
Здравствуйте, не удается перебрать foreachom значения. Возникает следующая ошибка: Оператор foreach не может использоваться для переменных...

Оператор foreach не работает с переменными типа так как не содержит открытого определения для getenumerator
Оператор foreach не работает с переменными типа &quot;Лаба_2.RList&quot; так как &quot;Лаба_2.RList&quot; не содержит открытого определения для...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Вывод данных через динамический список в справочнике
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Функция заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
10 пpимет, которые всегда сбываются
Maks 31.03.2026
1. Чтобы, наконец, пришла маршрутка, надо закурить. Если сигарета последняя, маршрутка придет еще до второй затяжки даже вопреки расписанию. 2. Нaдоели зима и снег? Не надо переезжать. Достаточно. . .
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 31.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
Functional First Web Framework Suave
DevAlt 30.03.2026
Sauve. IO Апнулись до NET10. Из зависимостей один пакет, работает одинаково хорошо как в режиме проекта так и в интерактивном режиме. из сложностей - чисто функциональный подход. Решил. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru