2011-06-20 57 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); 

優雅不是嗎?

相關問題