Имеет метод принимающий 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);
}
}
}
}
}
Здравствуйте, _NN_, Вы писали:
_NN>Имеет метод принимающий IEnumerable, который вызывает GetEnumerator несколько раз. _NN>Появилась необходимость на каждый вызов GetEnumerator возвращать разную последовательность. _NN>Есть вариант переделать метод и весь сопутствующий код.
_NN>Тут вот придумался другой вариант, где каждый вызов GetEnumerator возвращает другую последовательность. _NN>Не нарушает ли это решение каких нибудь контрактов или может есть проблемы о которых я не подозреваю ?
Очередное гениальное решение с претензией на нобелевскую премию
Здравствуйте, 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 передавать следующую последовательность или вот то, что я написал.
Здравствуйте, _NN_, Вы писали:
_NN>Тут вот придумался другой вариант, где каждый вызов GetEnumerator возвращает другую последовательность. _NN>Не нарушает ли это решение каких нибудь контрактов или может есть проблемы о которых я не подозреваю ?
нет конечно. любая concurrent коллекция может выдать разные последовательности на двух последовательных вызовах GetEnumerator
Здравствуйте, Jack128, Вы писали:
J>Здравствуйте, _NN_, Вы писали:
J>нет конечно. любая concurrent коллекция может выдать разные последовательности на двух последовательных вызовах GetEnumerator
Это хорошо.
Может тогда есть идеи насчёт имени метода и класса ?
Здравствуйте, _NN_, Вы писали:
_NN>Здравствуйте, Jack128, Вы писали:
J>>Здравствуйте, _NN_, Вы писали:
J>>нет конечно. любая concurrent коллекция может выдать разные последовательности на двух последовательных вызовах GetEnumerator
_NN>Это хорошо. _NN>Может тогда есть идеи насчёт имени метода и класса ?
IEnumerable в принципе это паттерн итератор, он может перебирать любые структуры данных в любом порядке.
Здравствуйте, _NN_, Вы писали:
_NN>Здравствуйте, Jack128, Вы писали:
J>>Здравствуйте, _NN_, Вы писали:
J>>нет конечно. любая concurrent коллекция может выдать разные последовательности на двух последовательных вызовах GetEnumerator
_NN>Это хорошо. _NN>Может тогда есть идеи насчёт имени метода и класса ?
А вот хз. Я не могу представить зачем может понадобиться такая последовательность в общем виде. А для конкретного метода, я б сделал как ты сам в ветке выше предлагал
В общем есть вариант поменять A ,чтобы умел принимать IEnumerable<IEnumerable<int>> и в CreateB передавать следующую последовательность
Здравствуйте, Jack128, Вы писали:
J>А вот хз. Я не могу представить зачем может понадобиться такая последовательность в общем виде. А для конкретного метода, я б сделал как ты сам в ветке выше предлагал J>
J>В общем есть вариант поменять A ,чтобы умел принимать IEnumerable<IEnumerable<int>> и в CreateB передавать следующую последовательность
Конкретно мне это нужно для тестов
Симулировать разное поведение.
Есть список который подаётся как приходящий извне и вот понадобилось выдавать разные последовательности но менять много кода в тестах не хочется .
Здравствуйте, _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
Так делать на практике можно, если все три условия соблюдаются:
1) Эти Enumerable нигде не доступны, их экземпляры нельзя получить через public/internal мемберы
2) вы используете некий фреймворк который требует на входе IEnumerable. и по другому сделать не можете.
3) вы про это написали камент в коде что бы кто то не нарушил пункт 1 своим обновлением
только это уже философия программирования касательно самого сложного принципа из пятерки SOLID.
Здравствуйте, Jack128, Вы писали:
_NN>>Тут вот придумался другой вариант, где каждый вызов GetEnumerator возвращает другую последовательность. _NN>>Не нарушает ли это решение каких нибудь контрактов или может есть проблемы о которых я не подозреваю ?
J>нет конечно. любая concurrent коллекция может выдать разные последовательности на двух последовательных вызовах GetEnumerator
Здравствуйте, _NN_, Вы писали:
_NN>Конкретно мне это нужно для тестов _NN>Симулировать разное поведение. _NN>Есть список который подаётся как приходящий извне и вот понадобилось выдавать разные последовательности но менять много кода в тестах не хочется .
Ну вы даете. Есть параметризированные тесты. И тесты, если завтра захочется паралельно запускать в рандомном порядке, то что будете делать?
Maintainability в общем ниже плинтуса — через три месяца ничего не поймешь что за треш написал три месяца назад
Здравствуйте, 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); }
}
}
Здравствуйте, VladCore, Вы писали:
J>>нет конечно. любая concurrent коллекция может выдать разные последовательности на двух последовательных вызовах GetEnumerator
VC>IEnumerable это же не коллекция.
А коллекция — это IEnumerable