Every time I need to do something N times inside an algorithm using C# I write this code
每次我需要使用c#在一个算法中做N次事情时,我都会写这段代码
for (int i = 0; i < N; i++)
{
...
}
Studying Ruby I have learned about method times() which can be used with the same semantics like this
学习Ruby时,我学到了方法times(),它可以像这样使用相同的语义
N.times do
...
end
Code fragment in C# looks more complex and we should declare useless variable i.
c#中的代码片段看起来更复杂,我们应该声明无用的变量i。
I tried to write extension method which returns IEnumerable, but I am not satisfied with the result because again I have to declare a cycle variable 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())
{
...
}
Is it possible using some new C# 3.0 language features to make N times cycle more elegant?
是否可能使用一些新的c# 3.0语言特性使N次循环更加优雅?
4 个解决方案
#1
48
A slightly briefer version of cvk's answer:
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);
}
}
}
Use:
使用:
5.Times(() => Console.WriteLine("Hi"));
5.Times(i => Console.WriteLine("Index: {0}", i));
#2
14
It is indeed possible with C# 3.0:
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);
}
Usage:
用法:
int sum = 0;
5.Times().Do( i =>
sum += i
);
Shamelessly stolen from http://grabbagoft.blogspot.com/2007/10/ruby-style-loops-in-c-30.html
无耻地偷了从http://grabbagoft.blogspot.com/2007/10/ruby -风格-环- c - 30. - html
#3
0
If you are using .NET 3.5 then you can use the extension method Each proposed in this article, and use it to avoid classic loop.
如果您正在使用。net 3.5,那么您可以使用本文中提出的每个扩展方法,并使用它来避免经典循环。
public static class IEnumerableExtensions
{
public static void Each<T>(
this IEnumerable<T> source,
Action<T> action)
{
foreach(T item in source)
{
action(item);
}
}
}
This particular extension method spot welds an Each method on anything that implements IEnumerable. You know this because the first parameter to this method defines what this will be inside the method body. Action is a pre-defined class that basically stands in for a function (delegate) returning no value. Inside the method, is where the elements are extracted from the list. What this method enables is for me to cleanly apply a function in one line of code.
这个特殊的扩展方法点焊每个实现IEnumerable的方法。您知道这一点,因为这个方法的第一个参数定义了这个方法主体内的内容。Action是一个预定义的类,它基本上代表一个函数(委托)不返回任何值。在方法内部,是从列表中提取元素的位置。这个方法允许我在一行代码中干净地应用一个函数。
(http://www.codeproject.com/KB/linq/linq-to-life.aspx)
(http://www.codeproject.com/KB/linq/linq-to-life.aspx)
Hope this helps.
希望这个有帮助。
#4
0
I wrote my own extension that add Times to Integer (plus some other stuff). You can get the code here : https://github.com/Razorclaw/Ext.NET
我编写了自己的扩展,将Times添加到Integer(加上其他一些东西)。您可以在这里获得代码:https://github.com/Razorclaw/Ext.NET
The code is very similar to Jon Skeet answer:
代码非常类似于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);
}
}
}
#1
48
A slightly briefer version of cvk's answer:
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);
}
}
}
Use:
使用:
5.Times(() => Console.WriteLine("Hi"));
5.Times(i => Console.WriteLine("Index: {0}", i));
#2
14
It is indeed possible with C# 3.0:
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);
}
Usage:
用法:
int sum = 0;
5.Times().Do( i =>
sum += i
);
Shamelessly stolen from http://grabbagoft.blogspot.com/2007/10/ruby-style-loops-in-c-30.html
无耻地偷了从http://grabbagoft.blogspot.com/2007/10/ruby -风格-环- c - 30. - html
#3
0
If you are using .NET 3.5 then you can use the extension method Each proposed in this article, and use it to avoid classic loop.
如果您正在使用。net 3.5,那么您可以使用本文中提出的每个扩展方法,并使用它来避免经典循环。
public static class IEnumerableExtensions
{
public static void Each<T>(
this IEnumerable<T> source,
Action<T> action)
{
foreach(T item in source)
{
action(item);
}
}
}
This particular extension method spot welds an Each method on anything that implements IEnumerable. You know this because the first parameter to this method defines what this will be inside the method body. Action is a pre-defined class that basically stands in for a function (delegate) returning no value. Inside the method, is where the elements are extracted from the list. What this method enables is for me to cleanly apply a function in one line of code.
这个特殊的扩展方法点焊每个实现IEnumerable的方法。您知道这一点,因为这个方法的第一个参数定义了这个方法主体内的内容。Action是一个预定义的类,它基本上代表一个函数(委托)不返回任何值。在方法内部,是从列表中提取元素的位置。这个方法允许我在一行代码中干净地应用一个函数。
(http://www.codeproject.com/KB/linq/linq-to-life.aspx)
(http://www.codeproject.com/KB/linq/linq-to-life.aspx)
Hope this helps.
希望这个有帮助。
#4
0
I wrote my own extension that add Times to Integer (plus some other stuff). You can get the code here : https://github.com/Razorclaw/Ext.NET
我编写了自己的扩展,将Times添加到Integer(加上其他一些东西)。您可以在这里获得代码:https://github.com/Razorclaw/Ext.NET
The code is very similar to Jon Skeet answer:
代码非常类似于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);
}
}
}