|
|
|
|
|
介紹
在 C# 中,你可以通過多種方式迭代列表,例如 for
循環(huán)、foreach
循環(huán)或使用 LINQ。當你使用一種List<T>
類型時,你甚至還有一個類型,即ForEach
方法,但是此方法并不總是顯示與普通 foreach
循環(huán)相同的行為。
使用代碼
List<T>
(不是 IList<T>
的 ForEach
)方法對存儲在列表中的每個對象執(zhí)行操作。通常它包含讀取或修改列表中的每個對象或對列表本身為每個對象執(zhí)行某些操作的代碼。
修改對象本身
以下示例使用一種ForEach
方法迭代集合中所有存儲的數(shù)字。它從每個數(shù)字中減去 10。最后,數(shù)字將打印到控制臺。它是否有效取決于你使用的數(shù)據(jù)類型!
List<int> items = new List<int>() { 14, 19 };
items.ForEach(item => item = item - 10);
foreach (int item in items)
{
Console.WriteLine(item);
}
在本例中,控制臺中的輸出是 14 和 19。如果類型是原始數(shù)據(jù)類型(.NET 中的結構),則該ForEach
方法不會產(chǎn)生你想要的效果。沒想到是這個結果,看了下ForEach
定義就明白了。它不能按設計工作!
//定義 List<T>.ForEach
public void ForEach(Action<T> action)
//定義 Action<T>
public delegate void Action<in T>(T obj)
Int
是一種值類型,這意味著它按值傳遞給方法。按值表示將對象的副本傳遞給方法,而不是對象本身。因此,如果傳遞到方法中的操作ForEach
更改了副本,但不會影響原始對象。所以在我們的示例中,原始的 int
值不會改變。委托Action
也沒有可用于更新列表中對象的返回類型。
修改集合
當你使用普通的 foreach
語句時,你無法在遍歷集合時添加或刪除項目。但是有了List.ForEach
你就可以了,所以下面的代碼可以毫無錯誤地執(zhí)行。
public class Integer
{
public int Value { get; set; }
public Integer(int value) { Value = value; }
}
public void Sample()
{
List<Integer> items = new List<Integer>()
{
new Integer(14),
new Integer(0),
new Integer(19)
};
items.ForEach(item =>
{
if (item.Value == 0)
{
items.Remove(item);
}
item.Value = item.Value - 10;
});
foreach (Integer item in items)
{
Console.WriteLine(item.Value);
}
}
控制臺顯示的結果是 4 和 19。所以這是一個很好的例子,不是所有你能做的,你也應該做!另一種方法,刪除一個項目,效果很好。似乎在內部使用了向后迭代,因此刪除有效,添加無效。
總結
因此,如果你想在通用列表中存儲結構對象,如 int
、long
、double
、bool
甚至 string
,如果你想避免出現(xiàn)問題,你應該使用普通的 foreach
(或 for
)。同樣在 ForEach
方法中刪除項目也是應該盡可能避免的事情。
參考:List<T>.For Each(Action<T>) 方法
命名空間:System.Collections.Generic
集合:System.Collections.dll
對List<T>
的每個元素執(zhí)行指定的操作。
public void ForEach (Action<T> action);
action:Action<T>
Action<T>
委托執(zhí)行List<T>
的每個元素。
ArgumentNullException
action
是null。
InvalidOperationException
集合中的一個元素已被修改。
下面的示例演示了如何使用Action<T>
委托打印List<T>
對象的內容。在此示例中,Print
方法用于將列表的內容顯示到控制臺。
筆記
除了使用Print
方法顯示內容外,C# 示例還演示了使用匿名方法將結果顯示到控制臺。
List<string> names = new List<string>();
names.Add("Bruce");
names.Add("Alfred");
names.Add("Tim");
names.Add("Richard");
// 使用“打印”方法顯示列表的內容。
names.ForEach(Print);
// 下面演示了C#的匿名方法特性,以向控制臺顯示列表的內容。
names.ForEach(delegate(string name)
{
Console.WriteLine(name);
});
void Print(string s)
{
Console.WriteLine(s);
}
/* 此代碼將產(chǎn)生類似于以下內容的輸出:
* Bruce
* Alfred
* Tim
* Richard
* Bruce
* Alfred
* Tim
* Richard
*/
解釋
Action<T>
是方法的委托,該方法對傳遞給它的對象執(zhí)行操作。當前List<T>
的元素分別傳遞給Action<T>
委托。
此方法是 O( n ) 操作,其中n是Count。
不支持修改Action<T>
委托主體中的基礎集合,這會導致未定義的行為。
相關文章