2011-06-20 56 views
28

在C#中,使用.NET Framework 4,是否有一种优雅的方式来重复相同的动作一定次数?例如,而不是:有没有一种优雅的方式来重复一个动作?

int repeat = 10; 
for (int i = 0; i < repeat; i++) 
{ 
    Console.WriteLine("Hello World."); 
    this.DoSomeStuff(); 
} 

我想写点东西像:

Action toRepeat =() => 
{ 
    Console.WriteLine("Hello World."); 
    this.DoSomeStuff(); 
}; 

toRepeat.Repeat(10); 

或:

Enumerable.Repeat(10,() => 
{ 
    Console.WriteLine("Hello World."); 
    this.DoSomeStuff(); 
}); 

我知道我可以创建自己的扩展方法的第一个例子,但是不存在使得它已经可以做到这一点的现有功能?

回答

22

有没有内置的方式来做到这一点。

原因是C#试图强化语言的功能和命令两方之间的差异。当C#不会产生副作用时,它使得编写函数式编程变得容易。因此,您可以获得像LINQ的Where,Select等收集操纵方法,但是可以获得you do not get ForEach

以类似的方式,你在这里试图做的是找到一些表达本质上是命令行为的功能方式。尽管C#为您提供了实现这一目的的工具,但它并不会尽力让您变得容易,因为这样做会使您的代码不清楚,也不会非惯用。

有一个,但不是IEnumerable<T>.ForEach。我认为的存在是源于框架设计师在.NET 2.0时代没有考虑过这些问题的历史人为因素;在3.0中明确划分的需求才变得明显。

+5

当然,没有什么能阻止你在IEnumerable上编写自己的副作用泛滥的'Repeat'或'ForEach'方法 - 语言设计师在那个时候洗了手。 – geofftnz

+0

我可以问为什么使用'ForEach'作为例子,这是一件坏事吗? – Coops

+1

@CodeBlend,这将是一个很好的问题。 – Joe

26

是否这样?

Enumerable.Range(0, 10).ForEach(arg => toRepeat()); 

这将执行您的方法10次。

[编辑]

我如此使用具有上可枚举ForEach扩展方法,我忘它不是FCL的一部分。

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

这里是你可以不ForEach扩展方法做什么:

Enumerable.Range(0, 10).ToList().ForEach(arg => toRepeat()); 

[编辑]

我认为最优雅的解决方案是实现可重复使用的方法:

public static void RepeatAction(int repeatCount, Action action) 
{ 
    for (int i = 0; i < repeatCount; i++) 
     action(); 
} 

用法:

RepeatAction(10,() => { Console.WriteLine("Hello World."); }); 
+2

旧的答案,但你也可以做'Enumerable.Range(0,10).Select(o =>/* return或do something * /)' –

+1

@ will-hart这很脏,不是很清楚看到你在做什么。编写扩展方法比滥用select来执行操作要好。 – Wolfsblvt

7

没有推出自己的扩展,我想你可以做这样的

Action toRepeat =() => { 
     Console.WriteLine("Hello World."); 
     this.DoSomeStuff(); 
    }; 

    int repeat = 10; 
    Enumerable.Range(0, repeat).ToList().ForEach(i => toRepeat()); 
7

东西对于一个班轮你可以这样做的简洁。不知道你在想什么......

Enumerable.Repeat<Action>(() => 
{ 
    Console.WriteLine("Hello World."); 
    this.DoSomeStuff(); 
}, 10).ToList().ForEach(x => x()); 
+2

o认为这不是优雅。与简单的陈述相比,这不易读,也难以理解。 – Ewerton

1
Table table = frame.AddTable(); 
int columnsCount = 7; 

Enumerable.Repeat<Func<Column>>(table.AddColumn, columnsCount) 
      .ToList() 
      .ForEach(addColumn => addColumn()); 
//or 
Enumerable.Range(0, columnsCount) 
      .ToList() 
      .ForEach(iteration => table.AddColumn()); 

这些选项,因为ToList()的不优雅,但对我来说都工作

0

声明一个扩展:

public static void Repeat(this Action action, int times){ 
    while (times-- > 0) 
     action.Invoke(); 
} 

您可以使用扩展方法:

 new Action(() => 
        { 
         Console.WriteLine("Hello World."); 
         this.DoSomeStuff(); 
        }).Repeat(10); 
0
Enumerable.Repeat<Action>(() => { Console.WriteLine("Hello World"); this.DoSomething(); },10); 

优雅不是吗?

相关问题