每次我需要在使用C#的算法内做N次时,我都会编写以下代码
for (int i = 0; i < N; i++)
{
...
}
在学习Ruby时,我了解了方法time(),它可以与类似的相同语义一起使用
N.times do
...
end
C#中的代码片段看起来更复杂,我们应该声明无用的变量i。
我试图编写返回IEnumerable的扩展方法,但我对结果不满意,因为我必须再次声明一个循环变量I。
public static class IntExtender
{
public static IEnumerable Times(this int times)
{
for (int i = 0; i < times; i++)
yield return true;
}
}
...
foreach (var i in 5.Times())
{
...
}
是否可以使用一些新的C#3.0语言功能使N时间循环更加优雅?
一个稍微简短的cvk答案版本:
public static class Extensions
{
public static void Times(this int count, Action action)
{
for (int i=0; i < count; i++)
{
action();
}
}
public static void Times(this int count, Action<int> action)
{
for (int i=0; i < count; i++)
{
action(i);
}
}
}
用途:
5.Times(() => Console.WriteLine("Hi"));
5.Times(i => Console.WriteLine("Index: {0}", i));
使用C#3.0:确实是可能的
public interface ILoopIterator
{
void Do(Action action);
void Do(Action<int> action);
}
private class LoopIterator : ILoopIterator
{
private readonly int _start, _end;
public LoopIterator(int count)
{
_start = 0;
_end = count - 1;
}
public LoopIterator(int start, int end)
{
_start = start;
_end = end;
}
public void Do(Action action)
{
for (int i = _start; i <= _end; i++)
{
action();
}
}
public void Do(Action<int> action)
{
for (int i = _start; i <= _end; i++)
{
action(i);
}
}
}
public static ILoopIterator Times(this int count)
{
return new LoopIterator(count);
}
用法:
int sum = 0;
5.Times().Do( i =>
sum += i
);
可耻地从http://grabbagoft.blogspot.com/2007/10/ruby-style-loops-in-c-30.html
如果您使用的是.NET 3.5,那么您可以使用本文中提出的扩展方法Each,并使用它来避免经典循环。
public static class IEnumerableExtensions
{
public static void Each<T>(
this IEnumerable<T> source,
Action<T> action)
{
foreach(T item in source)
{
action(item);
}
}
}
这个特殊的扩展方法点将Each方法焊接到任何实现IEnumerable。你知道这是因为这个方法定义了它将是什么方法主体内部。行动是预定义的类代表一个函数(委托)不返回任何值。在该方法内部,是提取元素的位置从列表中选择。这个方法是什么enables是为我干净地应用函数。
(http://www.codeproject.com/KB/linq/linq-to-life.aspx)
希望这能有所帮助。
我编写了自己的扩展,将Times添加到Integer(以及其他一些东西)。您可以在此处获取代码:https://github.com/Razorclaw/Ext.NET
代码与Jon Skeet的答案非常相似:
public static class IntegerExtension
{
public static void Times(this int n, Action<int> action)
{
if (action == null) throw new ArgumentNullException("action");
for (int i = 0; i < n; ++i)
{
action(i);
}
}
}