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