C# 3.0 㨠while(true) 㨠Iterator
åç½®ã
ããããï¼ãã¡ã¤ã«ãªã©ããï¼è¤æ°è¡ããã¹ããä¸è¡ãã¤èªã¿è¾¼ãå ´åã®ã½ã¼ã¹ã³ã¼ãã§ãã
using (StreamReader sr = new StreamReader(filePath)) { string line = string.Empty; while((line != sr.ReadLine()) != null) { // do something... } }ã¨ããããã
using (StreamReader sr = new StreamReader(filePath)) { for (string line = sr.ReadLine(); line != null; line = sr.ReadLine()) { // do something... } }ã®æ¹ã好ããªãã§ãã仲éã¯ããããªãï¼
è¡æ°ã®åé¡ã§ã¯ãªããä¸æå¤æ° line ã®æå¹ã¹ã³ã¼ããå¿ è¦ãªã«ã¼ãå ã ãã§åã¾ã£ã¦ãã®ã好ããªãã§ãã ã½ã¼ã¹ã³ã¼ãã¨ãã¦ã¯âãä¸çªèªã¿ããããã§ããããã©ããusing (StreamReader sr = new StreamReader(filePath)) { string line = string.Empty; while(true) { line = sr.ReadLine(); if(line != null) { // do something... } else { break; } } }æãä¸ã¤ç®ã®æ¸ãæ¹ã¯ãããã©äºã¤ç®ã¯ã ãã ã¨ãããããã¨ãããã¾ããã
ã¯ã£ãããã£ã¦èªã¿ããããèªã¿ã¥ããã¯åã¬ãã«ã ã¨æããã ãã©ã
ä¸ã¤ç®ã¯Webãªã©ã§å²ãã¨ä¸è¬çã«ç´¹ä»ããã¦ããããã§ããããã
ããããã¤ããªãã£
ã§ãããã§ãããä»ã®èªåã®å¥½ã¿ã§äºãã¨ãPythonã§ãã¸ã§ã¬ãã¼ã¿ã« ã¹ããªã¼ã ããã®åãåºããæ¼ãè¾¼ãã¦ãã¾ããããã§
æ¨é決ã¾ãwã ã¾ã while ã«ã¼ãã«ã¯ãªãã¾ããããforã®å½¢æ ãéãã¾ãããã
Python ã« generator ãããããã«ï¼C# 2.0 以éã§ã¯ yield æã使ããã®ã§ï¼ãããæ´»ç¨ããã®ã¯ã¾ãå½ç¶ã¨ãã¦ï¼ããã«ãã®å ã®è©±ã§ãï¼
3 å¹´åã®ã³ã¼ããæ¸ ç®ãã
2005 å¹´ã«*1 C# 2.0 ã®ãã¼ã¿çã使ãåºãã¦ä»¥æ¥ï¼ãããªãã®æ°ã® yield æãæ¸ãæ£ãããã¦ããï¼ãã®ãã¡ããªãã¯ï¼ä»¥ä¸ã©ã¡ããã® generic method ã§ç½®ãæãããã¨ãã§ããããããªããã¨æãï¼
static IEnumerable<TResult> Generate<TElement, TResult>( TElement element, Func<TElement, TResult> func) { while (true) { yield return func(element); } } static IEnumerable<TResult> Generate<TElement, TResult>( Func<TElement> initializer, Func<TElement, TResult> func) where TElement:IDisposable { using (var element = initializer()) { while (true) { yield return func(element); } } }
Generate ã¡ã½ããã®ä¸ã«åæ¢æ¡ä»¶ã¯æ¸ããªãã¦è¯ãï¼ããã¯å¤ã«æ¸ããï¼
å
ãã¿ã®ã½ã¼ã¹ã³ã¼ãã§èª¬æãããï¼
var lines = Generate(() => new StreamReader(filepath), sr => sr.ReadLine()) .TakeWhile(line => line != null); foreach (var line in lines) { // do something... }
ã¤ã¾ãããã§ååã¨ããããã ï¼ããããåæ¢æ¡ä»¶ã Generate ã¡ã½ããã®ä¸ã«æ¸ãã®ã¯ç¹æ®åãããï¼æ±ï¼ãã¼ããæãï¼
ã§ãï¼ãã® Generate ã£ã¦ã¡ã½ããï¼ã¾ã å解ã§ããããï¼
Repeat, Repeat, Repeat, ...
ä¸ã«å®ç¾©ãã Generate ã¡ã½ããã®æ£ä½ããåä¸è¦ç´ ã®ç¡éãªãã¼ãã+ãå°å½±ãã¨ãããã¨ã«æ°ä»ãã°ãã¨ã¯ç°¡åï¼ãå°å½±ã㯠C# 3.0 ã§æ¢ã«ããã®ã§ï¼å¿ è¦ãªã®ã¯ç¡éã«åä¸è¦ç´ ãè¿ã Repeat ã®æ¹ï¼ã¤ã¾ãçãã¯ããï¼
static partial class EnumerableEx { public static IEnumerable<T> Repeat<T>(T element) { while (true) { yield return element; } } public static IEnumerable<T> Repeat<T>(Func<T> elementInitializer) where T : IDisposable { using (var element = elementInitializer()) { while (true) { yield return element; } } } }
ã¦ãªããã§çµå±ãããªãï¼
var lines = EnumerableEx.Repeat(() => new StreamReader(filePath)) .Select(sr => sr.ReadLine()) .TakeWhile(line => line != null);
使ç¨ä¾
//ã©ã³ãã ã« 0 ãã 9 ã¾ã§ã®æ°ãè¿ãç¡éãªã¹ã var randomDigit = EnumerableEx.Repeat(new Random()) .Select(rand => rand.Next(0, 10)); //ä»ãã 10 ç§ä»¥å ã«éãï¼true ãè¿ãç¶ããç¡éãªã¹ã var timer = EnumerableEx.Repeat(DateTime.Now.AddSeconds(10.0)) .TakeWhile(time => DateTime.Now <= time) .Select(time => true);
ææ½°ãç·¨
ããããå
ã¯ãã ã®éã³ï¼
EnumerableEx.Repeat ã®åæååãã¨ããã¼ã¸ã§ã³ãã where T : IDisposable ã¨ããå¶ç´ãæ¶ãã¦ã¿ãï¼ãã ã T ã IDisposable ã ã£ãã¨ãã®åä½ã¯å¤ããªãã¾ã¾ï¼ã©ãããã¨ãã«ä¾¿å©ãã¨ããã¨ããããã®ï¼
//æåã®è¦ç´ ãè©ä¾¡ããæå»ããã¡ããã© 10 ç§éï¼çµäºæå»ã¾ã§ã®æ®ãæéãè¿ãç¶ããç¡éãªã¹ã var resttime = EnumerableEx.Repeat(() => DateTime.Now.AddSeconds(10.0)) .Select(time => time - DateTime.Now) .TakeWhile(span => span.TotalSeconds > 0);
boxing ãåé¿ãã¤ã¤ã®å¶ç´å¤ãã®ãã¯ããã¯ã¯æ» å¤ã«åºçªããªãã®ã§ï¼ç·´ç¿ãã¦ãã«ãã£ã¦ã¿ãï¼ã¾ãå¤å㧠IDisposable ã£ã¦ã®ã¯ã¾ããªããããã©ï¼
static partial class EnumerableEx { public static IEnumerable<T> Repeat<T>(T element) { while (true) { yield return element; } } public static IEnumerable<T> Repeat<T>(Func<T> elementInitializer) { return RepeatImpl<T>.Default.Repeat(elementInitializer); } private class RepeatImpl<T> { public virtual IEnumerable<T> Repeat(Func<T> elementInitializer) { var element = elementInitializer(); while (true) { yield return element; } } public static readonly RepeatImpl<T> Default; static RepeatImpl() { Type t = typeof(T); if (typeof(IDisposable).IsAssignableFrom(t)) { var implType = typeof(RepeatImplWithUsing<>).MakeGenericType(t); Default = Activator.CreateInstance(implType) as RepeatImpl<T>; } else { Default = new RepeatImpl<T>(); } } } private sealed class RepeatImplWithUsing<U> : RepeatImpl<U> where U : IDisposable { public override IEnumerable<U> Repeat(Func<U> elementInitializer) { using (var element = elementInitializer()) { while (true) { yield return element; } } } } }
ããªã²ã¼ã好ããªäººã®ããã®å¥è§£ï¼
static partial class EnumerableEx { public static IEnumerable<T> Repeat<T>(T element) { while (true) { yield return element; } } public static IEnumerable<T> Repeat<T>(Func<T> elementInitializer) { return RepeatImpl<T>.Repeat(elementInitializer); } private static class RepeatImpl<T> { public static IEnumerable<T> Repeat(Func<T> elementInitializer) { return _repeat(elementInitializer); } private static readonly Func<Func<T>, IEnumerable<T>> _repeat; static RepeatImpl() { Type t = typeof(T); if (typeof(IDisposable).IsAssignableFrom(t)) { Func<Func<IDisposable>, IEnumerable<IDisposable>> dummy = RepeatWithUsing<IDisposable>; _repeat = Delegate.CreateDelegate( typeof(Func<Func<T>, IEnumerable<T>>), dummy.Method.GetGenericMethodDefinition().MakeGenericMethod(t) ) as Func<Func<T>, IEnumerable<T>>; } else { _repeat = RepeatWithoutUsing; } } private static IEnumerable<T> RepeatWithoutUsing(Func<T> elementInitializer) { var element = elementInitializer(); while (true) { yield return element; } } private static IEnumerable<U> RepeatWithUsing<U>(Func<U> elementInitializer) where U : IDisposable { using (var element = elementInitializer()) { while (true) { yield return element; } } } } }
éå»ã®é¢é£è¨äº
- [.NET]Ruby 1.9.0 Enumerable ã¢ã¸ã¥ã¼ã«ã¨ LINQ Standard Operators 対å¿è¡¨ - NyaRuRuã®æ¥è¨
- Enumerable ãå¶ãããã®ã¯ C# ãå¶ããï¼åã ãã©ï¼
- [.NET][Python]IEnumerator è²ã
- NyaRuRuã®æ¥è¨
- Python 2.4 以åã®ãã¤ãã¬ã¼ã¿å®ã¶ãããåé¡ãã¨ã
- [.NET][Python]å¾ç¶ C# - NyaRuRuã®æ¥è¨
- [.NET]å¹çã®è¯ãå®è¡æãã¤ã³ãã£ã³ã°ã¨ã¤ã³ã¿ã¼ãã§ã¤ã¹æåããã°ã©ãã³ã°ã§ã® boxing ã®åé¿ãã¯ããã¯
- ãããªãã¨æ°ã«ãã人ãå°æ°æ´¾ãªã®ã¯ããã£ã¦ã¾ã
*1:ã²ãã£ã¨ããã 2004 å¹´ã ã£ããã