任何模仿C#中的time()Ruby方法的机会



每次我需要在使用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);
        }
    }
}

最新更新