Здравствуйте, _NN_, Вы писали:
_NN>Тут вот придумался другой вариант, где каждый вызов GetEnumerator возвращает другую последовательность. _NN>Не нарушает ли это решение каких нибудь контрактов или может есть проблемы о которых я не подозреваю ?
нет конечно. любая concurrent коллекция может выдать разные последовательности на двух последовательных вызовах GetEnumerator
Имеет метод принимающий 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 передавать следующую последовательность или вот то, что я написал.
Здравствуйте, 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