Множественное использование IEnumerable
От: _NN_ www.nemerleweb.com
Дата: 15.08.20 13:49
Оценка:
Имеет метод принимающий IEnumerable, который вызывает GetEnumerator несколько раз.
Появилась необходимость на каждый вызов GetEnumerator возвращать разную последовательность.
Есть вариант переделать метод и весь сопутствующий код.

Тут вот придумался другой вариант, где каждый вызов GetEnumerator возвращает другую последовательность.
Не нарушает ли это решение каких нибудь контрактов или может есть проблемы о которых я не подозреваю ?

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
    internal class MultiEnumerable<T> : IEnumerable<T>
    {
        private IEnumerable<IEnumerable<T>> _source;

        public MultiEnumerable(IEnumerable<IEnumerable<T>> source)
        {
            _source = source;
        }

        public IEnumerator<T> GetEnumerator()
        {
            var current = _source.Take(1).First();
            _source = _source.Skip(1);
            return current.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }

    public static class MultiEnumerableExtension
    {
        public static IEnumerable<T> AsMultiEnumerable<T>(this IEnumerable<IEnumerable<T>> source)
        {
            return new MultiEnumerable<T>(source);
        }
    }

    static class Program
    {
        public static void Main()
        {
            IEnumerable<IEnumerable<int>> arrayOfArray =
                new[]
                {
                    new[] {1}, new[] {2}, new[] {3}, new[] {4}
                };

            IEnumerable<int> arrayOfArrayAsEnumerable = arrayOfArray.AsMultiEnumerable();

            for (int x = 0; x < 4; x++)
            {
                Console.WriteLine("---");
                foreach (var i in arrayOfArrayAsEnumerable)
                {
                    Console.WriteLine(i);
                }
            }
        }
    }
}


---
1
---
2
---
3
---
4

http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Множественное использование IEnumerable
От: VladCore  
Дата: 15.08.20 13:58
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Имеет метод принимающий IEnumerable, который вызывает GetEnumerator несколько раз.

_NN>Появилась необходимость на каждый вызов GetEnumerator возвращать разную последовательность.
_NN>Есть вариант переделать метод и весь сопутствующий код.

_NN>Тут вот придумался другой вариант, где каждый вызов GetEnumerator возвращает другую последовательность.

_NN>Не нарушает ли это решение каких нибудь контрактов или может есть проблемы о которых я не подозреваю ?

Очередное гениальное решение с претензией на нобелевскую премию

Озвучьте для начала проблему. Аж интересно стало.
Re[2]: Множественное использование IEnumerable
От: _NN_ www.nemerleweb.com
Дата: 15.08.20 14:03
Оценка:
Здравствуйте, VladCore, Вы писали:

VC>Очередное гениальное решение с претензией на нобелевскую премию


VC>Озвучьте для начала проблему. Аж интересно стало.


Вроде я и озвучил.
Имеем что-то вроде

class A
{
 IEnumerable<int> ints;
 public A(IEnumerable<int> ints) => _ints=ints;

 public B CreateB() => new B(_ints);
}

class B 
{ 
 public B(IEnumerable<int> ints)
 {
  foreach (int i in ints) { Console.WriteLine(i); }
 } 
}



Мне надо чтобы A.CreateB каждый раз получал другую последовательность, а не работал с той же самой.
В общем есть вариант поменять A ,чтобы умел принимать IEnumerable<IEnumerable<int>> и в CreateB передавать следующую последовательность или вот то, что я написал.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Множественное использование IEnumerable
От: Jack128  
Дата: 15.08.20 17:07
Оценка: 12 (2)
Здравствуйте, _NN_, Вы писали:

_NN>Тут вот придумался другой вариант, где каждый вызов GetEnumerator возвращает другую последовательность.

_NN>Не нарушает ли это решение каких нибудь контрактов или может есть проблемы о которых я не подозреваю ?

нет конечно. любая concurrent коллекция может выдать разные последовательности на двух последовательных вызовах GetEnumerator
Отредактировано 15.08.2020 17:09 Jack128 . Предыдущая версия .
Re[2]: Множественное использование IEnumerable
От: _NN_ www.nemerleweb.com
Дата: 15.08.20 17:12
Оценка:
Здравствуйте, Jack128, Вы писали:

J>Здравствуйте, _NN_, Вы писали:


J>нет конечно. любая concurrent коллекция может выдать разные последовательности на двух последовательных вызовах GetEnumerator


Это хорошо.
Может тогда есть идеи насчёт имени метода и класса ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Множественное использование IEnumerable
От: Qulac Россия  
Дата: 15.08.20 17:19
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Здравствуйте, Jack128, Вы писали:


J>>Здравствуйте, _NN_, Вы писали:


J>>нет конечно. любая concurrent коллекция может выдать разные последовательности на двух последовательных вызовах GetEnumerator


_NN>Это хорошо.

_NN>Может тогда есть идеи насчёт имени метода и класса ?

IEnumerable в принципе это паттерн итератор, он может перебирать любые структуры данных в любом порядке.
Программа – это мысли спрессованные в код
Re[3]: Множественное использование IEnumerable
От: Jack128  
Дата: 15.08.20 17:24
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Здравствуйте, Jack128, Вы писали:


J>>Здравствуйте, _NN_, Вы писали:


J>>нет конечно. любая concurrent коллекция может выдать разные последовательности на двух последовательных вызовах GetEnumerator


_NN>Это хорошо.

_NN>Может тогда есть идеи насчёт имени метода и класса ?

А вот хз. Я не могу представить зачем может понадобиться такая последовательность в общем виде. А для конкретного метода, я б сделал как ты сам в ветке выше предлагал

В общем есть вариант поменять A ,чтобы умел принимать IEnumerable<IEnumerable<int>> и в CreateB передавать следующую последовательность

Re[4]: Множественное использование IEnumerable
От: _NN_ www.nemerleweb.com
Дата: 15.08.20 17:27
Оценка:
Здравствуйте, Jack128, Вы писали:

J>А вот хз. Я не могу представить зачем может понадобиться такая последовательность в общем виде. А для конкретного метода, я б сделал как ты сам в ветке выше предлагал

J>

J>В общем есть вариант поменять A ,чтобы умел принимать IEnumerable<IEnumerable<int>> и в CreateB передавать следующую последовательность


Конкретно мне это нужно для тестов
Симулировать разное поведение.
Есть список который подаётся как приходящий извне и вот понадобилось выдавать разные последовательности но менять много кода в тестах не хочется .
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Множественное использование IEnumerable
От: VladCore  
Дата: 16.08.20 00:55
Оценка:
Здравствуйте, _NN_, Вы писали:

VC>>Очередное гениальное решение с претензией на нобелевскую премию


VC>>Озвучьте для начала проблему. Аж интересно стало.


_NN>Вроде я и озвучил.

_NN>Имеем что-то вроде

_NN>
_NN>class A
_NN>{
_NN> IEnumerable<int> ints;
_NN> public A(IEnumerable<int> ints) => _ints=ints;

_NN> public B CreateB() => new B(_ints);
_NN>}

_NN>class B 
_NN>{ 
_NN> public B(IEnumerable<int> ints)
_NN> {
_NN>  foreach (int i in ints) { Console.WriteLine(i); }
_NN> } 
_NN>}
_NN>



_NN>Мне надо чтобы A.CreateB каждый раз получал другую последовательность, а не работал с той же самой.

_NN>В общем есть вариант поменять A ,чтобы умел принимать IEnumerable<IEnumerable<int>> и в CreateB передавать следующую последовательность или вот то, что я написал.

Это именно решение. Проблемы они по другому выглядят.

Например "Secure communication in insecure environment such as the internet". Это проблема. Решение у нее — https
Re[3]: Так делать можно, если
От: VladCore  
Дата: 16.08.20 01:02
Оценка:
Здравствуйте, _NN_, Вы писали:

Так делать на практике можно, если все три условия соблюдаются:

1) Эти Enumerable нигде не доступны, их экземпляры нельзя получить через public/internal мемберы
2) вы используете некий фреймворк который требует на входе IEnumerable. и по другому сделать не можете.
3) вы про это написали камент в коде что бы кто то не нарушил пункт 1 своим обновлением

только это уже философия программирования касательно самого сложного принципа из пятерки SOLID.
Отредактировано 16.08.2020 1:04 VladCore . Предыдущая версия . Еще …
Отредактировано 16.08.2020 1:03 VladCore . Предыдущая версия .
Re[2]: Множественное использование IEnumerable
От: VladCore  
Дата: 16.08.20 01:08
Оценка:
Здравствуйте, Jack128, Вы писали:

_NN>>Тут вот придумался другой вариант, где каждый вызов GetEnumerator возвращает другую последовательность.

_NN>>Не нарушает ли это решение каких нибудь контрактов или может есть проблемы о которых я не подозреваю ?

J>нет конечно. любая concurrent коллекция может выдать разные последовательности на двух последовательных вызовах GetEnumerator


IEnumerable это же не коллекция.
Re[5]: Множественное использование IEnumerable
От: VladCore  
Дата: 16.08.20 01:11
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Конкретно мне это нужно для тестов

_NN>Симулировать разное поведение.
_NN>Есть список который подаётся как приходящий извне и вот понадобилось выдавать разные последовательности но менять много кода в тестах не хочется .

Ну вы даете. Есть параметризированные тесты. И тесты, если завтра захочется паралельно запускать в рандомном порядке, то что будете делать?

Maintainability в общем ниже плинтуса — через три месяца ничего не поймешь что за треш написал три месяца назад
Отредактировано 16.08.2020 1:16 VladCore . Предыдущая версия .
Re[6]: Множественное использование IEnumerable
От: _NN_ www.nemerleweb.com
Дата: 16.08.20 05:09
Оценка:
Здравствуйте, VladCore, Вы писали:

VC>Ну вы даете. Есть параметризированные тесты. И тесты, если завтра захочется паралельно запускать в рандомном порядке, то что будете делать?

Это мне не поможет.
Мне нужно на каждый GetEnumerator вернуть другую последовательность.

VC>Maintainability в общем ниже плинтуса — через три месяца ничего не поймешь что за треш написал три месяца назад


Альтернатива это добавить перегрузку для IEnumerable<IEnumerable>.

static class EnumerableUtils
{
 static IEnumerable<T> GetFirstSequenceAndAdvanceToNextSequence<T>(ref IEnumerable<IEnumerable<T>> source)
 {
   var res = source.First();
   source = source.Skip(1);
   return res;
 }
}

class A
{
 IEnumerable<IEnumerable<int>> ints;
 public A(IEnumerable<IEnumerable<int>> ints) => _ints=ints;
 public A(IEnumerable<int> ints) : this(new[] { ints }) {}

 public B CreateB() => new B(GetFirstSequenceAndAdvanceToNextSequence(ref _ints));
}

class B 
{ 
 public B(IEnumerable<int> ints)
 {
  foreach (int i in ints) { Console.WriteLine(i); }
 } 
}


Вот и вопрос а нужно ли это усложнение.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Отредактировано 16.08.2020 5:33 _NN_ . Предыдущая версия .
Re[3]: Множественное использование IEnumerable
От: Jack128  
Дата: 16.08.20 12:52
Оценка:
Здравствуйте, VladCore, Вы писали:

J>>нет конечно. любая concurrent коллекция может выдать разные последовательности на двух последовательных вызовах GetEnumerator


VC>IEnumerable это же не коллекция.

А коллекция — это IEnumerable
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.