2008-10-07 3 views
29

Cada vez que tengo que hacer algo N veces dentro de un algoritmo usando C# escribo este códigoCualquier posibilidad de imitar los tiempos() Método de Ruby en C#?

for (int i = 0; i < N; i++) 
{ 
    ... 
} 

El estudio de Rubí he aprendido sobre el método veces() que se puede utilizar con la misma semántica como este fragmento de código

N.times do 
    ... 
end 

en C# parece más complejo y que debe declarar la variable i inútil .

Traté de escribir método de extensión que devuelve IEnumerable , pero no estoy satisfecho con el resultado porque una vez más tengo que declarar una variable de ciclo 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()) 
{ 
    ... 
} 

¿Es posible utilizar algunas nuevas características del lenguaje C# 3.0 para hacer N tiempos de ciclo más elegante?

Respuesta

48

Un poco más breve versión de cvk's answer:

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); 
     } 
    } 
} 

Uso:

5.Times(() => Console.WriteLine("Hi")); 
5.Times(i => Console.WriteLine("Index: {0}", i)); 
14

hecho, es posible con 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); 
} 

Uso:

int sum = 0; 
5.Times().Do(i => 
    sum += i 
); 

robado Desvergonzadamente de http://grabbagoft.blogspot.com/2007/10/ruby-style-loops-in-c-30.html

0

Si está utilizando .NET 3.5, puede utilizar el método de extensión Cada uno propuesto en este artículo, y lo usa para evitar el loop clásico.

public static class IEnumerableExtensions 
    { 
     public static void Each<T>(
     this IEnumerable<T> source, 
     Action<T> action) 
     { 
      foreach(T item in source) 
      { 
       action(item); 
      } 
     } 
    } 

Esta extensión método punto particular soldaduras un Cada método en cualquier cosa que implementa IEnumerable. Usted sabe esto porque el primer parámetro para este método define lo que será dentro del cuerpo del método. La acción es una clase predefinida que, básicamente, representa una función (delegado) que no devuelve ningún valor. Dentro del método, es donde se extraen los elementos de la lista. Lo que este método habilita es para mí aplicar limpiamente una función en una línea de código.

(http://www.codeproject.com/KB/linq/linq-to-life.aspx)

Espero que esto ayude.

+0

No es realmente lo que quería, pero útil también. ¡Gracias! –

0

escribí mi propia extensión que añadir Times para Entero (además de algunas otras cosas).Puede obtener el código aquí: https://github.com/Razorclaw/Ext.NET

El código es muy similar a la respuesta de 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); 
     } 
    } 
} 
Cuestiones relacionadas