C#中有“upto”方法吗?

时间:2011-11-17 08:13:59

标签: c#

这里有一些代码可以打印出从0到9的数字的平方:

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

通过for循环从0到N加1是一个非常常见的习惯用法。

这是表达此问题的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));

我的问题是,标准C#库是否带有类似上述UpTo的内容?

理想情况下,我想要一种方法让'UpTo'成为所有整数对象的方法。所以我能做到:

var n = 10;

n.UpTo(...);

这在C#中是否可行?

6 个答案:

答案 0 :(得分:49)

将其变为extension method(请注意n参数之前的 this ,该参数定义此方法操作的类型):

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

如果您想要包含上限,请将<更改为<=

答案 1 :(得分:24)

查看LINQ TakeWhile或您的特定整数情况,使用Enumerable.Range

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

可以说你不应该在那里放置一个Action,请参阅comments on ForEach here

答案 2 :(得分:9)

试试这个:

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课程中,您可以编写所有方法;将它们分组到同一个静态类中可以让您轻松管理它们。

答案 3 :(得分:8)

想在一条线上做吗?在这里:

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

答案 4 :(得分:6)

尝试Enumerable.Range,可能与TakeTakeWhile结合使用:

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

ForEach上有一个List<T>可以用来更接近你想要的语法,但我认为它很糟糕。它采用纯查询/过滤器/转换语法,以有效的不可变方式工作,并引入副作用。

为了您将来的娱乐,您可以查看extension methodsIEnumerable<T>yield return。当您将这三种内容组合使用时,可以实现许多生成器类型的功能和有趣的语法。虽然我认为这个特定的例子并不是使用它们的最佳位置,因为结果语法变得一团糟。

答案 5 :(得分:2)

在静态类“Extensions”中创建这样的方法,例如:

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

希望这有帮助! :)