Подтвердить что ты не робот

Есть ли метод "upto" в С#?

Здесь немного кода, который выводит квадраты чисел от 0 до 9:

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

Выполнение чего-то от 0 до N на 1 через цикл for - очень распространенная идиома.

Здесь используется метод UpTo, который выражает это:

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

Пример квадратов выше:

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

Мой вопрос в том, имеет ли стандартная библиотека С# что-то вроде выше UpTo?

В идеале, мне бы хотелось, чтобы метод "UpTo" был методом для всех целых объектов. Поэтому я мог бы сделать:

var n = 10;

n.UpTo(...);

Возможно ли это в С#?

4b9b3361

Ответ 1

Поверните его в метод расширения (обратите внимание на этот перед параметром n, который определяет тип этот метод работает):

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

Использование:

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

Примечание. Вышеупомянутый вызов метода не является особенно интуитивным. Помните, что код записывается один раз и читается много раз.

Возможно, что-то вроде ниже может быть немного лучше, но, честно говоря, я все равно просто напишу цикл foreach.

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

Если вы этого хотели, тогда вы можете написать метод расширения следующим образом:

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

Измените < на <=, если вы хотите включить верхнюю границу.

Ответ 2

Посмотрите на LINQ TakeWhile или на свой конкретный случай целых чисел, используйте Enumerable.Range

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

Возможно, вы не должны помещать действие в конец там, см. комментарии к ForEach здесь.

Ответ 3

Попробуйте следующее:

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

С этим вы можете написать

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

Функция, которую я написал, называется методом расширения.
Во время разработки вы заметите, что это не родная функция, потому что у нее есть другой значок.
Методы Estension являются статическими методами или функциями, включенными в статический класс, и тип, над которым они работают, является первым параметром, на котором вы должны использовать ключевое слово this.
В классе IntExtensions вы можете написать все методы, которые вам нравятся; группировка их внутри одного и того же статического класса упрощает управление ими.

Ответ 4

Хотите сделать это в одной строке? вот оно:

Enumerable.Range(0, 9).Select(i => i * i).ToList().ForEach(j=>Console.WriteLine("%d",j));

Ответ 5

Попробуйте Enumerable.Range, возможно, в комбинации с Take или 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);
}

В List<T> есть ForEach, который можно использовать для получения более синтаксиса для того, что вы хотите, но я считаю его плохим. Он принимает чистый синтаксис query/filter/transform, который работает эффективно неизменно и вводит побочные эффекты.

Для вашего будущего развлечения вы можете проверить методы расширения, IEnumerable<T> и yield return. Множество функциональных возможностей генератора и интересный синтаксис становятся возможными, когда вы используете эти три вещи в сочетании. Хотя я бы сказал, что этот конкретный пример - не лучшее место для их использования, потому что полученный синтаксис становится беспорядком.

Ответ 6

Сделайте свой метод следующим образом в статическом классе "Расширения", например:

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

И использование:

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

Надеюсь, это поможет!:)