2008-10-07 6 views
29

Chaque fois que je dois faire quelque chose N fois dans un algorithme utilisant C# J'écris ce codeToutes les chances d'imiter times() Méthode Ruby en C#?

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

étude Ruby J'ai appris sur la méthode fois() qui peut être utilisé avec la même sémantique comme ce

N.times do 
    ... 
end 
fragment de code

en C# ressemble plus complexe et nous devons déclarer la variable inutile i.

J'ai essayé d'écrire méthode d'extension qui retourne IEnumerable, mais je ne suis pas satisfait du résultat parce qu'encore une fois, je dois déclarer une variable cycle 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()) 
{ 
    ... 
} 

Est-il possible à l'aide des nouvelles fonctionnalités du langage C# 3.0 pour faire N cycle de fois plus élégant?

Répondre

48

légèrement version de cvk's answer brève:

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

Utilisation:

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

Il est en effet possible avec 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); 
} 

Utilisation:

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

Shamelessly volé http://grabbagoft.blogspot.com/2007/10/ruby-style-loops-in-c-30.html

0

Si vous utilisez .NET 3.5, vous pouvez alors utiliser la méthode d'extension Chacun proposé dans cet article, et l'utiliser pour éviter la boucle classique.

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

Ce particulier spot méthode d'extension soudures une Chaque méthode sur tout ce qui implémente IEnumerable. Vous savez cela parce que le premier paramètre à cette méthode définit ce que ce sera à l'intérieur du corps de la méthode. Action est une classe prédéfinie qui, fondamentalement, représente une fonction (délégué) ne renvoyant aucune valeur. À l'intérieur de la méthode, est l'endroit où les éléments sont extraits de la liste. Ce que permet cette méthode est pour moi d'appliquer proprement une fonction dans une ligne de code.

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

Hope this helps.

+0

Pas vraiment ce que je voulais, mais utile aussi. Merci! –

0

J'ai écrit mon propre extension qui ajoutent à temps entier (plus d'autres choses).Vous pouvez obtenir le code ici: https://github.com/Razorclaw/Ext.NET

Le code est très similaire à la réponse 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); 
     } 
    } 
} 
Questions connexes