29 votes

Avez-vous des chances d'imiter la méthode Ruby times () en C #?

Chaque fois que j'ai besoin de faire quelque chose de N fois à l'intérieur d'un algorithme à l'aide de C# j'écris ce code

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

L'étude de Ruby, j'ai appris à propos de la méthode des moments() qui peut être utilisé avec la même sémantique comme ceci

N.times do
    ...
end

Fragment de Code C# a l'air plus complexe et nous devons déclarer inutile variable - je.

J'ai essayé d'écrire une extension de la méthode qui retourne IEnumerable, mais je ne suis pas satisfait du résultat, car, encore une fois, je dois déclarer un cycle variable - je.

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 de quelques nouvelles de C# 3.0 fonctionnalités de langage pour faire de la N des temps de cycle plus élégant?

49voto

Jon Skeet Points 692016

Une version légèrement plus brève de la réponse de 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);
        }
    }
}
 

Utilisation:

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

14voto

cvk Points 598

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

Usage:

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

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

0voto

Anthony Garcia Points 603

J'ai écrit ma propre extension qui ajoute Times à Integer (ainsi que d'autres choses). Vous pouvez obtenir le code ici: https://github.com/Razorclaw/Ext.NET

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X