IObservable sequence from *Async method - c#

I have a list of source elements Foo, and an asynchronous method GetBoosAsync() to convert them to elements of type Boo:
public class Foo
{
public string Value { get; set; }
}
public class Boo
{
public string Value { get; set; }
}
static void Main(string[] args)
{
IReadOnlyCollection<Foo> foos = GetFoos();
Task<IReadOnlyCollection<Boo>> boosTask = GetBoosAsync(foos);
boosTask.Wait();
foreach (Boo boo in boosTask.Result)
{
Console.WriteLine(boo.Value);
}
Console.ReadKey();
}
public static IReadOnlyCollection<Foo> GetFoos()
{
return Enumerable.Range(1, 100).Select(i => new Foo
{
Value = i.ToString(CultureInfo.CurrentCulture)
}).ToList();
}
public static async Task<IReadOnlyCollection<Boo>> GetBoosAsync(IReadOnlyCollection<Foo> foos)
{
List<Task<Boo>> booTasks = foos.Select(ConvertFooToBooAsync).ToList();
// Waiting for ALL conversions of Foos to Boos
await Task.WhenAll(booTasks.ToArray<Task>());
return booTasks.Select(booTask => booTask.Result).ToList();
}
public static Task<Boo> ConvertFooToBooAsync(Foo foo)
{
return Task.Factory.StartNew(() =>
{
Thread.Sleep(100);
return new Boo { Value = foo.Value };
});
}
The method GetBoosAsync() calls ConvertFoosToBoosAsync for each element, waits for completion of all conversions and then returns list of results.
The problem:
How to implement the method GetBoosAsync to return IObservable<Boo> instead, and asynchronously return individual elements as they get processed?
i.e.
public static IObservable<Boo> OGetBoos(IReadOnlyCollection<Foo> foos)
{
...
}
and use it like this:
static void Main(string[] args)
{
IReadOnlyCollection<Foo> foos = GetFoos();
IObservable<Boo> boos = OGetBoos(foos);
boos = boos.Do(boo =>
{
Console.WriteLine(boo.Value);
});
boos.Wait();
Console.ReadKey();
}

Would this work for you:
public static IObservable<Boo> OGetBoos(IReadOnlyCollection<Foo> foos)
{
var query =
from f in foos.ToObservable()
from b in ConvertFooToBooAsync(f).ToObservable()
select b;
return query;
}
BTW, thanks for easy to compile working code in your question!

You can try this approach as well.
public static IObservable<Boo> GetBoosAsync(IEnumerable<Foo> foos)
{
return foos.Select(t => Observable.FromAsync(() => ConvertFooToBooAsync(t))).Merge();
}

Related

C# Type T return with Func<T> delegate as argument

I have this mapping function to convert types when migrating services to keep the return types compatible -
private T JsonMap<T>(object obj)
{
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(obj));
}
but what I find myself doing a lot is -
public async Task<T1> DoWork(T2 obj)
{
var requestMapped = JsonMap<T3>(obj);
var response = await _myService.DoWork(requestMapped);
var responseMapped = JsonMap<T1>(response);
return responseMapped;
}
As a result, I was trying to think of a way to incorporate that into the JsonMap function, but having difficulties there. Trying to have something like -
public async T1 JsonMap<T1>(object obj, Func<T3,T4> myFunc)
{
var requestMapped = JsonMap<T3>(obj);
var response = await myFunc(requestMapped);
var responseMapped = JsonMap<T1>(response);
return responseMapped;
}
and use it like this -
public async Task<T1> DoWork(T2 obj)
{
return await JsonMap<T1>(obj, _myService.DoWork);
}
but I'm not too sure how that would work in terms of delegates. If someone could help point me in the right direction that would be helpful.
You could use declared delegates and pass them to your generic process.
I have updated the example to make it async, at the end of the day you should be able to call
Converter c = new Converter();
TestType2 tt2 = new TestType2() { testValue = "Something to test" };
TestType1 tt1 = await c.JsonMap<TestType1, TestType2>(tt2);
I have put an example as RexTester
using Newtonsoft.Json;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace ConsoleApp1
{
public class TestType1
{
public string testValue { get; set; }
}
public class TestType2
{
public string testValue { get; set; }
}
public class TestType3
{
public string testValue { get; set; }
}
public class Conversion
{
public System.Type ConverionType { get; set; }
public object ConversionFunction { get; set; }
}
public class Converter
{
public delegate Task<T> processingFuncDel<T, T1>(T1 value);
Dictionary<System.Type, Conversion> conversionDelegates = new Dictionary<System.Type, Conversion>();
public Converter()
{
processingFuncDel<TestType2, TestType3> convert3To2 = new processingFuncDel<TestType2, TestType3>(myFunc);
Conversion c = new Conversion() { ConverionType = typeof(TestType3), ConversionFunction = convert3To2 };
conversionDelegates.Add(typeof(TestType3), c);
// Add more converters here
}
public async Task<T1> JsonMap<T1, T2>(T2 obj)
{
if (conversionDelegates.ContainsKey(obj.GetType()))
{
System.Type ct = conversionDelegates[obj.GetType()].ConverionType;
if(ct == typeof(TestType3))
{
return await JsonMap<T1, T2, TestType3>(obj, (processingFuncDel<T2, TestType3>)conversionDelegates[obj.GetType()].ConversionFunction);
}
// Add more cases here, or use reflection to try an do it dynamically...
}
return default(T1);
}
public async Task<T1> JsonMap<T1, T2, T3>(T2 obj, processingFuncDel<T2, T3> myFunc)
{
T3 requestMapped = JsonMap<T3>(obj);
T2 response = await myFunc(requestMapped);
T1 responseMapped = JsonMap<T1>(response);
return responseMapped;
}
public T JsonMap<T>(object obj)
{
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(obj));
}
public async Task<TestType2> myFunc(TestType3 obj)
{
// Do your async processing here, this is just an example
TestType2 ret = new TestType2() { testValue = obj.testValue };
return ret;
}
}
public class Program
{
public static void Main(string[] args)
{
Converter c = new Converter();
TestType2 tt2 = new TestType2() { testValue = "Something to test" };
// Make an async call to convert
TestType1 tt1 = c.JsonMap<TestType1, TestType2>(tt2).GetAwaiter().GetResult();
}
}
}
Asynchronous delegates are just like regular delegates, except the return type is wrapped in Task<>. So in your case, you'd want something like Func<T1, Task<T2>>:
public async Task<T1> JsonMap<T1, T3, T4>(object obj, Func<T3, Task<T4>> myFunc)
{
var requestMapped = JsonMap<T3>(obj);
var response = await myFunc(requestMapped);
var responseMapped = JsonMap<T1>(response);
return responseMapped;
}
The problem with very-generic methods like this is that the consumer has to specify all the type parameters explicitly. C# doesn't allow you to specify only the first parameter and infer the other two:
_ = await JsonMap<T1, T3, T4>(obj, _myService.DoWork);
You can work around this with a few type tricks, e.g.:
public static class JsonMapper<T1>
{
public static async Task<T1> Map<T3, T4>(object obj, Func<T3, Task<T4>> myFunc)
{
var requestMapped = JsonMap<T3>(obj);
var response = await myFunc(requestMapped);
var responseMapped = JsonMap<T1>(response);
return responseMapped;
}
}
which can be used as:
_ = await JsonMapper<T1>.Map(obj, _myService.DoWork);
Alternatively, you can drop the final mapping from your implementation:
public async Task<T4> JsonMap<T3, T4>(object obj, Func<T3, Task<T4>> myFunc)
{
var requestMapped = JsonMap<T3>(obj);
var response = await myFunc(requestMapped);
return response;
}
which can be used as:
_ = await JsonMap<T1>(JsonMap(obj, _myService.DoWork));
Doesn't answer your question exactly, but you might be able to reach your goal of simpler code simply by changing JsonMap to an extension method.
static public T JsonMap<T>(this object obj)
{
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(obj));
}
Now DoWork is one line:
public Task<T1> DoWork(T2 obj)
{
return _myService.DoWork(obj.JsonMap<T3>()).JsonMap<T1>;
}

Associating Enums with string c#

Following This post : Associating enums with strings in C#
I wanted to go further as it didn't quite fully met my needs for a Enum like Class that would act as string I ended-up with a solution that allows me to do the following:
string test1 = TestEnum.Analyze; //test1 == "ANALYZE"
string test1bis = (string)TestEnum.Analyze; //test1bis == "ANALYZE"
TestEnum test2 = "ANALYZE"; //test2 == {ANALYZE}
TestEnum test3 = "ANYTHING"; //test3 == null
As seen below in the unitTests all these work fine with this:
public class TestEnum : EnumType<TestEnum>
{
public static TestEnum Analyze { get { return new EnumType<TestEnum>("ANALYZE"); } }
public static TestEnum Test { get { return new EnumType<TestEnum>("TEST"); } }
public static implicit operator TestEnum(string s) => (EnumType<TestEnum>) s;
public static implicit operator string(TestEnum e) => e.Value;
}
I can't decide if this solution is elegant or incredibly stupid, It seems to me probably unnecessary complex and I might be messing a much easier solution in any case it could help someone so I'm putting this here.
//for newtonsoft serialization
[JsonConverter(typeof(EnumTypeConverter))]
public class EnumType<T> where T : EnumType<T> , new()
{
public EnumType(string value= null)
{
Value = value;
}
//for servicestack serialization
static EnumType()
{
JsConfig<EnumType<T>>.DeSerializeFn = str =>
{
return (T)str ;
};
JsConfig<EnumType<T>>.SerializeFn = type =>
{
return type.Value;
};
JsConfig<T>.DeSerializeFn = str =>
{
return (T)str;
};
JsConfig<T>.SerializeFn = type =>
{
return type.Value;
};
}
protected string Value { get; set; }
public static T Parse(string s)
{
return (T)s;
}
public override string ToString()
{
return Value;
}
public static EnumType<T> ParseJson(string json)
{
return (T)json;
}
public static implicit operator EnumType<T>(string s)
{
if (All.Any(dt => dt.Value == s))
{
return new T { Value = s };
}
else
{
var ai = new Microsoft.ApplicationInsights.TelemetryClient(Connector.tconfiguration);
ai.TrackException(new Exception($"Value {s} is not acceptable value for {MethodBase.GetCurrentMethod().DeclaringType}, Acceptables values are {All.Select(item => item.Value).Aggregate((x, y) => $"{x},{y}")}"));
return null;
}
}
public static implicit operator string(EnumType<T> dt)
{
return dt?.Value;
}
public static implicit operator EnumType<T>(T dt)
{
if (dt == null) return null;
return new EnumType<T>(dt.Value);
}
public static implicit operator T(EnumType<T> dt)
{
if (dt == null) return null;
return new T { Value = dt.Value };
}
public static bool operator ==(EnumType<T> ct1, EnumType<T> ct2)
{
return (string)ct1 == (string)ct2;
}
public static bool operator !=(EnumType<T> ct1, EnumType<T> ct2)
{
return !(ct1 == ct2);
}
public override bool Equals(object obj)
{
try
{
if(obj.GetType() == typeof(string))
{
return Value == (string)obj;
}
return Value == obj as T;
}
catch(Exception ex)
{
return false;
}
}
public override int GetHashCode()
{
return (!string.IsNullOrWhiteSpace(Value) ? Value.GetHashCode() : 0);
}
public static IEnumerable<T> All
=> typeof(T).GetProperties()
.Where(p => p.PropertyType == typeof(T))
.Select(x => (T)x.GetValue(null, null));
//for serialisation
protected EnumType(SerializationInfo info,StreamingContext context)
{
Value = (string)info.GetValue("Value", typeof(string));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Value",Value);
}
}
Here are the unit tests:
[TestFixture]
public class UnitTestEnum
{
Connector cnx { get;set; }
private class Test
{
public TestEnum PropertyTest { get; set; }
public string PropertyString { get; set; }
}
[SetUp]
public void SetUp()
{
typeof(EnumType<>)
.Assembly
.GetTypes()
.Where(x => x.BaseType?.IsGenericType == true && x.BaseType.GetGenericTypeDefinition() == typeof(EnumType<>))
.Each(x =>
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(x.BaseType.TypeHandle)
);
cnx = new Connector();
}
[TearDown]
public void Clear()
{
cnx.Dispose();
}
[Test]
public void EqualsString()
{
Assert.AreEqual(TestEnum.Analyze, TestEnum.Analyze);
Assert.AreEqual(TestEnum.Analyze,"ANALYZE");
Assert.IsTrue("ANALYZE" == TestEnum.Analyze);
Assert.IsTrue("ANALYZE".Equals(TestEnum.Analyze));
}
[Test]
public void Casts()
{
string test1 = TestEnum.Analyze;
string test1bis = (string)TestEnum.Analyze;
TestEnum test2 = "ANALYZE";
TestEnum test3 = "NAWAK";
Assert.AreEqual("ANALYZE", test1);
Assert.AreEqual("ANALYZE", test1bis);
Assert.IsTrue(test2 == TestEnum.Analyze);
Assert.IsTrue(test2.Equals(TestEnum.Analyze));
Assert.AreEqual(test3, null);
}
[Test]
public void Deserializations()
{
new List<TestEnum>
{
(TestEnum)ServiceStack.Text.JsonSerializer.DeserializeFromString("\"ANALYZE\"", typeof(TestEnum)),
"\"ANALYZE\"".FromJson<TestEnum>(),
(TestEnum)Newtonsoft.Json.JsonConvert.DeserializeObject("\"ANALYZE\"", typeof(TestEnum)),
Newtonsoft.Json.JsonConvert.DeserializeObject<TestEnum>("\"ANALYZE\"")
}.Each(testEnum => Assert.AreEqual(testEnum, TestEnum.Analyze));
new List<Test>
{
"{\"PropertyTest\":\"ANALYZE\",\"PropertyString\":\"ANALYZE\"}".FromJson<Test>(),
(Test)ServiceStack.Text.JsonSerializer.DeserializeFromString("{\"PropertyTest\":\"ANALYZE\",\"PropertyString\":\"ANALYZE\"}", typeof(Test)),
Newtonsoft.Json.JsonConvert.DeserializeObject<Test>("{\"PropertyTest\":\"ANALYZE\",\"PropertyString\":\"ANALYZE\"}"),
(Test)Newtonsoft.Json.JsonConvert.DeserializeObject("{\"PropertyTest\":\"ANALYZE\",\"PropertyString\":\"ANALYZE\"}",typeof(Test))
}.Each(test =>
{
Assert.AreEqual(test.PropertyTest, TestEnum.Analyze);
Assert.AreEqual(test.PropertyString, "ANALYZE");
});
}
[Test]
public void Serialisations()
{
Assert.AreEqual("{\"PropertyTest\":\"ANALYZE\",\"PropertyString\":\"ANALYZE\"}", new Test { PropertyTest = TestEnum.Analyze, PropertyString = TestEnum.Analyze }.ToJson());
Assert.AreEqual("{\"PropertyTest\":\"ANALYZE\",\"PropertyString\":\"ANALYZE\"}", Newtonsoft.Json.JsonConvert.SerializeObject(new Test { PropertyTest = TestEnum.Analyze, PropertyString = TestEnum.Analyze }));
Assert.AreEqual("\"ANALYZE\"", TestEnum.Analyze.ToJson());
Assert.AreEqual("\"ANALYZE\"", Newtonsoft.Json.JsonConvert.SerializeObject(TestEnum.Analyze));
}
[Test]
public void TestEnums()
{
Assert.AreEqual(TestEnum.All.Count(), 2);
Assert.Contains(TestEnum.Analyze,TestEnum.All.ToList());
Assert.Contains(TestEnum.Test,TestEnum.All.ToList());
}
Elegant code is typically described as simple, clean, terse with clear intent and optimally performant, I'm not seeing any of these traits here which is especially convoluted as instead of using simple C# Enum's as intended they're wrapped in a generic base class with implicit casts and custom serialization handling for different JSON Serialization libraries (that's unlikely to work in other serialization libraries/formats) and with with all the additional artificial complexity added it's not even clear what the benefit or purpose of all the boilerplate is?
Code that's drowned in so much boilerplate increases the maintenance burden and inhibits refactoring as no one else is going to know what the desired intent or purpose of the code is meant to be & why simpler naive solutions weren't adopted instead.
If you just want to have a different Wire Serialization format to the Symbol name used in code (which IMO should have a good reason for being different), you can just use the [EnumMember] Serialization attribute:
[DataContract]
public enum TestEnum
{
[EnumMember(Value = "ANALYZE")]
Analyze,
[EnumMember(Value = "TEST")]
Test,
}
Otherwise I'd dispense with using Enums and go back to using string constants, which are simpler, faster, memory efficient and works in all Serialization libraries without custom serialization hacks:
public static class MyConstants
{
public const string Analyze = "ANALYZE";
public const string Test = "TEST";
}

Chaining C# LINQ , in a Rails-scope-like way

I have the following class where I store some static data. I have as well a couple methods to filter that data, using LINQ. Like this:
static class Data {
// ...
static public Weapon[] weapons = new Weapon[] {
// ...
}
static public GetUnlockedWeapons() {
Data.weapons.Where( a => a.unlocked ).ToArray();
}
static public GetWeaponsType(string type) {
Data.weapons.Where( a => a.type == type ).ToArray();
}
// ...
}
But now I am seeing that this way is not very flexible. As I build more filters, combining them is quite hard and/or verbose.
I come from Ruby on Rails development, where there ActiveRecord has something like scopes that are chainable.
I was wondering if there was some way for me to chain my filters, in a way similar to this:
weapons = Data.weapons.unlocked().type("sword").andMore().andEvenMore();
Yes, you can do it like this:
static class Data {
// ...
static public Weapon[] weapons = new Weapon[] {
// ...
}
public static IEnumerable<Weapon> GetUnlockedWeapons(this IEnumerable<Weapon> weapons) {
return weapons.Where( a => a.unlocked );
}
public static IEnumerable<Weapon> GetWeaponsType(this IEnumerable<Weapon> weapons, string type) {
return weapons.Where( a => a.type == type );
}
// ...
}
And using it:
var weapons = Data.weapons.GetUnlockedWeapons().GetWeaponsType("pistol").AndMore().ToList();
There's no point returning an Array, since it's likely you'll chain it. Leave the materialization of the collection up to the caller (in this case we're using ToList)
How about defining your filters as extension methods to the IEnumerable<Weapon> type:
public static class Data
{
public Weapon[] GetUnlockedWeapons(this IEnumerable<Weapon> weapons)
{
return weapons.Where( a => a.unlocked ).ToArray();
}
public static Weapon[] GetWeaponsType(this IEnumerable<Weapon> weapons, string type)
{
return weapons.Where( a => a.type == type ).ToArray();
}
}
and now assuming that you have a list of weapons you could apply those filters to it:
Weapon[] weapons = new Weapon[]
{
// ...
};
weapons = weapons.unlocked().type("sword").andMore().andEvenMore();
Alternatively you could define an API that is using the so called fluent interface:
public class Data
{
public Data(Weapon[] weapons)
{
this.Weapons = weapons;
}
public Weapon[] weapons { get; private set; }
public Data GetUnlockedWeapons()
{
return new Data(this.Weapons.Where( a => a.unlocked ).ToArray());
}
public Data GetWeaponsType(this IEnumerable<Weapon> weapons, string type)
{
return new Data(this.Weapons.Where( a => a.type == type ).ToArray());
}
}
and then use like this:
Weapon[] weapons = new Weapon[]
{
// ...
};
weapons = new Data(weapons).unlocked().type("sword").andMore().andEvenMore().Weapons;
public static class WeaponFilters
{
public static Weapon[] GetUnlocked(this Weapon[] w)
{
return w.Where(x=> x.unlocked).ToArray();
}
public static Weapon[] Type(this Weapon[] w, string type)
{
return w.Where(x=> x.type == type).ToArray();
}
//some more filters...
}
Then You can use it like:
weapons = weapons.unlocked().type("sword");

wrap anonymous function with another call

I have this code in which I am trying to wrap an anonymous function by another call so when it is actually the wrapper's value that is returned and not the original function's.
In the code below however I get a NullPointerException in the last call. I am sure I am not doing something right, but beats me what it is.
class Program
{
public class MyClass
{
public int MyProp { get; set; }
}
private static List<Func<MyClass, object>> Calls;
private static object ExtraCall(int obj)
{
var returnVal = 8;
//do some stuff
return returnVal;
}
static void Main(string[] args)
{
Calls = new List<Func<MyClass, object>>();
Calls.Add(c => c.MyProp);
Func<MyClass, object> func = c => c.MyProp;
Calls.Add(c => ExtraCall((int)func(func.Target as MyClass)));
var obj = new MyClass(){ MyProp = 7 };
var test1 = Calls[0](obj);
var test2 = Calls[1](obj);
}
}
func.Target is null because this delegate doesn't have any instance which it is invoked on. You can try following code:
Calls.Add(c => ExtraCall((int)func(c)));

C#: Circular enumeration of IEnumerable<T>

There is the command hierarchy in my current application.
public interface ICommand
{
void Execute();
}
So, some commands are stateful, some are not.
I need to enumerate IEnumerable in the circular way for some command implementation during command execution.
public class GetNumberCommand : ICommand
{
public GetNumberCommand()
{
List<int> numbers = new List<int>
{
1, 2, 3
};
}
public void Execute()
{
// Circular iteration here.
// 1 => 2 => 3 => 1 => 2 => 3 => ...
}
public void Stop()
{
// Log current value. (2 for example)
}
}
Execute is called from time to time, so it is necessary to store the iteration state.
How to implement that circular enumeration?
I have found two solutions:
Using the IEnumerator<T> interface.
It looks like:
if (!_enumerator.MoveNext())
{
_enumerator.Reset();
_enumerator.MoveNext();
}
Using the circular IEnumerable<T> (yield forever the same sequence): “Implementing A Circular Iterator” - HonestIllusion.Com.
Maybe, there are more ways to achieve it.
What would you recommend to use and why?
Instead of dealing with IEnumerator interface,
foreach (var x in GetSomething())
{
if (someCondition) break;
}
public IEnumerable<int> GetSomething()
{
List<int> list = new List<int>() { 1, 2, 3 };
int index=0;
while (true)
yield return list[index++ % list.Count];
}
Here's one I just implemented as an extension.
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace DroopyExtensions
{
public static class CircularEnumaratorExtensionMethod
{
public static IEnumerator<T> GetCircularEnumerator<T>(this IEnumerable<T> t)
{
return new CircularEnumarator<T>(t.GetEnumerator());
}
private class CircularEnumarator<T> : IEnumerator<T>
{
private readonly IEnumerator _wrapedEnumerator;
public CircularEnumarator(IEnumerator wrapedEnumerator)
{
this._wrapedEnumerator = wrapedEnumerator;
}
public object Current => _wrapedEnumerator.Current;
T IEnumerator<T>.Current => (T)Current;
public void Dispose()
{
}
public bool MoveNext()
{
if (!_wrapedEnumerator.MoveNext())
{
_wrapedEnumerator.Reset();
return _wrapedEnumerator.MoveNext();
}
return true;
}
public void Reset()
{
_wrapedEnumerator.Reset();
}
}
}
}
To use it, all you have to do is
using DroopyExtensions;
class Program
{
static void Main(string[] args)
{
var data = new List<string>() {"One", "Two", "Tree"};
var dataEnumerator = data.GetCircularEnumerator();
while(dataEnumerator.MoveNext())
{
Console.WriteLine(dataEnumerator.Current);
}
}
}
You can use this extension method:
public static IEnumerable<T> Cyclic<T>(this IEnumerable<T> #this)
{
while (true)
foreach (var x in #this)
yield return x;
}
In that way:
public class GetNumberCommand : ICommand
{
private readonly IEnumerator<int> _commandState = new[] { 1, 2, 3 }.Cyclic().GetEnumerator();
public void Execute()
{
_commandState.MoveNext();
var state = _commandState.Current;
//
// Do stuff with state
//
}
public void Stop()
{
var state = _commandState.Current;
// Log state value. (2 for example)
}
}
while (!stop)
{
foreach (var i in numbers)
{
// do something
}
}
I think, the most comfortable way wil be to implement custom collection with custom enumerator and encapsulate circular logic in it.
class Collection<T> : IEnumerable<T>
{
bool circle;
List<T> collection = new List<T>();
public IEnumerable<T> IEnumerable<T>.GetEnumerator()
{
if(circle) return new CustomEnumerator<T>(this);
return circle.GetEnumerator();
}
}
class CustomEnumerator : Enumerator<T> {}
something like this...
You can write a circular enumerable without yield returns.
public class CircularEnumerable<T> : IEnumerable<T>
{
public CircularEnumerable (IEnumerable<T> sequence)
{
InfiniteLoop = sequence.Concat (this);
}
private readonly IEnumerable<T> InfiniteLoop;
public IEnumerator<T> GetEnumerator ()
{
return InfiniteLoop.GetEnumerator ();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
{
return InfiniteLoop.GetEnumerator ();
}
}
public class GetNumberCommand : ICommand
{
public GetNumberCommand()
{
List<int> numbers = new List<int>
{
1, 2, 3
};
infiniteLoopOnNumbers = new CircularEnumerable<int>(numbers).GetEnumerator();
}
IEnumerator<int> infiniteLoopOnNumbers;
public void Execute()
{
infiniteLoopOnNumbers.MoveNext();
}
public void Stop()
{
int value = infiniteLoopOnNumbers.Current;
}
}

Categories