Is there an “upto” method in C#?

前端 未结 6 1786
攒了一身酷
攒了一身酷 2021-02-18 14:31

Here\'s a bit of code which prints out the squares of the numbers from 0 to 9:

for (int i = 0; i < 10; i++)
    Console.WriteLine(i*i);

Doin

相关标签:
6条回答
  • 2021-02-18 14:40

    Turn it into an extension method (note the this before the n parameter, which defines the type this method operates on):

    static class MathUtil
    {
        public static void UpTo(this int n, Action<int> proc)
        {
            for (int i = 0; i < n; i++)
                proc(i);
        }
    }
    

    Usage:

    10.UpTo((i) => Console.WriteLine(i * i));
    

    Note: The above method call isn't particularly intuitive though. Remember code is written once and read many times.

    Maybe allowing something like below might be slightly better, but to be honest i'd still just write a foreach loop.

    0.UpTo(10 /*or 9 maybe*/, (i) => Console.WriteLine(i * i));
    

    If you wanted this, then you could write an extension method like this:

    public static void UpTo(this int start, int end, Action<int> proc)
    {
        for (int i = start; i < end; i++)
            proc(i);
    }
    

    Change < to <= if you want an inclusive upper bound.

    0 讨论(0)
  • 2021-02-18 14:42

    Take a look at LINQ TakeWhile or for your specific case of integers, use Enumerable.Range

    Enumerable.Range(1, 10).Select(i => ...);
    

    Arguably you shouldn't be putting an Action on the end there, see comments on ForEach here.

    0 讨论(0)
  • 2021-02-18 14:44

    Try this:

    public static class IntExtensions
    {
        public static void UpTo(this int n, Action<int> proc)
        {
            for (int i = 0; i < n; i++)
                proc(i);
        }
    }
    

    With this you could write

    10.UpTo(i => Console.WriteLine(i * i));
    

    The function I wrote is called an extension method.
    At design time you notice is not a native function because it has a different icon.
    Estension methods are static methods or functions included in a static class and type they work on is the first param on which you must use this keyword.
    In IntExtensions class you could write all methods you please; grouping them inside the same static class makes you easy manage them.

    0 讨论(0)
  • 2021-02-18 14:53

    Try Enumerable.Range, possibly in combination with Take or TakeWhile:

    IEnumerable<int> values = Enumerable.Range(0, 20)
        .Take(10); // Not necessary in this example
    
    foreach(var value in values)
    {
        Console.WriteLine(value);
    }
    
    // or ...
    
    foreach(var i in Enumerable.Range(0, 10))
    {
        Console.WriteLine(i * i);
    }
    

    There is a ForEach on List<T> that you could use to get closer syntax to what you want, but I consider it bad form. It takes a pure query/filter/transform syntax, that works in an effectively immutable fashion, and introduces side-effects.

    For your future amusement you might want to check out extension methods, IEnumerable<T>, and yield return. A lot of generator-type functionality and interesting syntax becomes possible when you use those three things in combination. Although I would argue that this particular example isn't the best place to use them because the resulting syntax becomes a mess.

    0 讨论(0)
  • 2021-02-18 14:54

    wanna do it in one line ? here it goes:

    Enumerable.Range(0, 9).Select(i => i * i).ToList().ForEach(j=>Console.WriteLine("%d",j));
    
    0 讨论(0)
  • 2021-02-18 15:07

    Make your method like this in a static class "Extensions" for example:

    public static void UpTo(this int n, Action<int> proc)
    {
        for (var i = 0; i < n; i++)
            proc(i);
    }
    

    And the usage:

    var n = 10;
    n.UpTo(i => Console.WriteLine(i * i));
    

    Hope this helps! :)

    0 讨论(0)
提交回复
热议问题