问这个问题我很愚蠢,但是我很难理解foreach。举例来说,我正在制作一个Book Store应用程序,同时具有Book类和Inventory类。 Inventory类具有removeBook方法,该方法可从清单中删除一本书。该方法的参数为int bookID。我想我应该使用foreach来完成此任务。我了解foreach的最基本用法,但是我不知道如何使用它来基本上选择特定的bookID,该方法是该方法中的一个参数。有人可以帮我指出正确的方向吗?
这是一个代码段,我知道该方法是错误的:
List<Book> Books = new List<Book>
{
new Book{ bookID = 5, Name = "Moby Dick", Price = 20.00 },
new Book{ bookID = 2, Name = "50 Shades of Grey", Price = 0.99 }
};
public void removeBook(int bookID)
{
foreach (var bookID in Books)
{
Products.Remove(book);
}
}
答案 0 :(得分:3)
从集合中删除东西并不是foreach的目的-它是对集合中的每个值执行一些操作。如果您要删除具有特定ID的图书,则可以使用常规的for循环:
// in Inventory class having List<Book> Books,
// assuming Book has a public int Id property
public void RemoveBook(int bookId) {
for (int i = 0; i < this.Books.Count; i++) {
if (this.Books[i].Id == bookId) {
this.Books.RemoveAt(i);
return;
}
}
}
如果由于某种原因(不应该是-ID应该是唯一的)存在任何重复项,并且您想删除所有具有给定ID的书籍,则此代码应执行以下操作:
public void RemoveBooks(int bookId) {
// iterating from the end of the array
// to prevent skipping over items
for (int i = this.Books.Count - 1; i >= 0; i--) {
if (this.Books[i].Id == bookId) {
this.Books.RemoveAt(i);
}
}
}
编辑:由于Gerardo Grignoli
,修复了代码答案 1 :(得分:2)
因此,如果您要从列表中删除一本书,则不必使用foreach
循环。最简单的方法是在List上使用RemoveAll
函数。
public void RemoveBook(int bookId) =>
Books.RemoveAll(book => book.Id == bookId);
答案 2 :(得分:0)
函数看起来像这样
void RemoveBook(int bookId)
{
foreach(Book book in booksRepository)
{
if(book.Id == bookId)
{
[here you have your method of choice of removing book from container]
//so for example if your container is list it could look like
//booksRepository.Remove(book)
}
}
}
但是,如果您正在寻找优雅的解决方案,则应考虑使用Linq
答案 3 :(得分:0)
foreach
如果要遍历同一列表,将无法正常工作,因此请使用for循环或linq
foreach语句用于遍历集合以获取所需的信息,但不能用于在源集合中添加或删除项,以避免不可预期的副作用。如果需要从源集合中添加或删除项目,请使用for循环。
private void RemoveBookFromInventory(int bookID)
{
foreach(Books book in listOfBooks)
{
if(book.bookID == bookID)
{
listOfBooks.Remove(book); //wont work
}
}
for(int i=0;i<listOfBooks.Count();i++)
{
if (listOfBooks[i].bookID == bookID)
listOfBooks.Remove(listOfBooks[i]);
}
}
答案 4 :(得分:0)
如果有
List<Thing> things = ....
然后在这样的foreach中
foreach (Thing theThing in things)
{
// do something with "theThing"
}
foreach
遍历things
列表中的所有项,并为每个连续值执行该代码块(在{ }
之间),该代码块存储在{{1}中}变量(类型为theThing
)。
您可以将Thing
替换为Thing theThing
,以获得完全相同的结果。
答案 5 :(得分:0)
正如其他人所暗示的那样,在使用for循环遍历列表时,您不能真正更改列表的内容,因为那样会更改您正在处理的数据结构。
不过,还有其他几种方法可以解决此问题。我个人喜欢这种风格的解决方案,您首先要获取该书的索引,然后在另一个步骤中将其删除:
var bookID = 2;
int? index = Books
// Generate a list of book- and position- pairs:
.Select((book, pos) => new {book, pos})
// First matching pair (or null):
.FirstOrDefault(set => set.book.bookID == bookID)?
// If NULL was not returned, get the index property:
.pos;
// Removal is only attempted if a matching book was found:
if(index.HasValue){
Books.RemoveAt(index.Value);
}