Từ 1 tới 9 trên tổng số 9 kết quả

Đề tài: tại sao không được phép gọi phương thức Remove (item) trong 1 vòng lặp Foreach ?

  1. #1
    Ngày gia nhập
    10 2009
    Nơi ở
    gầm cầu
    Bài viết
    156

    Mặc định tại sao không được phép gọi phương thức Remove (item) trong 1 vòng lặp Foreach ?

    chẳng hạn dòng code
    Visual C# Code:
    1. foreach (var item in danhsach) // danhsach là tên 1 List <T>
    2.     {
    3.           danhsach.Remove (item)
    4.     }
    sẽ báo lỗi Collection was modified; enumeration operation may not execute
    mình nghe nói chuyển sang dùng vòng lặp for sẽ hết lỗi và đúng là hết thật
    nhưng bản chất việc này là gì ? xin các bạn chỉ ra giúp

  2. #2
    Ngày gia nhập
    07 2007
    Nơi ở
    TP HCM
    Bài viết
    66

    foreach dùng để duyệt hết phần tử của một tập hợp. Công dụng của nó là để duyệt qua và lấy thông tin của từng phần tử ( dùng cho so sách hoặc trích xuất giá trị của các phần tử ). Bạn không thể duyệt các phần tử rồi thay đổi nội dụng của nó giữa chừng được( bao gồm thêm, xóa, sửa ) . Cái này là hạn chế của foreach rồi

    Dùng for loop trong trường hợp muốn thay đổi vậy

    Theo MSDN

    The foreach statement is used to iterate through the collection to get the information that you want, but can not be used to add or remove items from the source collection to avoid unpredictable side effects. If you need to add or remove items from the source collection, use a for loop.
    Ngoài ra, về lý do tại sao ko thể remove ( hay là add ) item được thì đó là do thao tác remove, add làm thay đổi cấu trúc thứ tự của danhsach.

    foreach không giống như for loop, foreach không sử dụng index ( ví dụ for loop dùng : danhsach[1], danhsach[2] ) mà sử dụng IEnumerable để nhảy qua từng phần tử một.

    Khi bạn xóa một phần tử hoặc thêm một phần tử thì ngay sau dòng lệnh thêm/xóa đó, cấu trúc của danhsach thay đổi rồi. Như vậy nó không đảm bảo là foreach sẽ chạy đúng nữa. Bắt buộc phải dừng ngay và update lại danhsach trước khi chạy lại foreach. Để tránh kiểu lập trình như vậy, compiler không cho phép code như vậy
    Đã được chỉnh sửa lần cuối bởi trandatnh : 24-07-2013 lúc 09:59 AM.

  3. #3
    Ngày gia nhập
    05 2010
    Bài viết
    1

    Thumbs down Cách dùng remove trong foreach

    Có thể được nếu sau khi remove xong thi thoát ra luon
    Ex:

    Code:
            public void RemoveByName(String name) 
            {
                foreach(StudentAP st in stList)
                {
                    if (st.FullName.Equals(name))
                    {
                        stList.Remove(st);
                        break;
                    }
    
                }
            }

  4. #4
    Ngày gia nhập
    04 2011
    Bài viết
    7

    Trích dẫn Nguyên bản được gửi bởi Phantom.like Xem bài viết
    Có thể được nếu sau khi remove xong thi thoát ra luon
    Ex:

    Code:
            public void RemoveByName(String name) 
            {
                foreach(StudentAP st in stList)
                {
                    if (st.FullName.Equals(name))
                    {
                        stList.Remove(st);
                        break;
                    }
    
                }
            }
    theo như bác thì khi chạy foreach thì khi dùng đến Remove thì lại thoát ah. bác có cách nào khác không. Mình cũng bị nhiều rồi nhưng đành phải dùng vòng lặp for để thay thế. thanks bác

  5. #5
    Ngày gia nhập
    08 2011
    Nơi ở
    Yên Bái- Hà Nội
    Bài viết
    961

    Mình cũng bị như bạn và phải chuyển sang for thật. Bạn TranDAt cung cấp thông tin chuẩn đó. Nếu bạn vẫn cứ muốn dùng Foreach thì thử dùng một cái dsTam=danhSach. Sau đó foreach với cái dsTam, remove ở danhsach coi thế nào( t chưa thử đâu, ý tưởng thế thôi). hi
    Skype: mrfour.it - Yahoo:mrfour_it
    Gmail: mrfour.it@gmail.com
    Bạn muốn học lập trình? Bạn chưa có kiến thức cơ bản? Bạn muốn học từ cơ bản tới nâng cao?... Bạn muốn có source code để tham khảo? Muốn có người hỗ trợ khi học?....http://www.laptrinh123.com sẽ giúp bạn những điều đó!

  6. #6
    Ngày gia nhập
    10 2010
    Bài viết
    35

    Mặc định tại sao không được phép gọi phương thức Remove (item) trong 1 vòng lặp Foreach ?

    Bạn dùng cách sau sẽ có thể xóa được. Bạn có thể linh động chuyển nó sang For đều được

    Code:
    while (i <= qEmpLst.Count - 1)
    {
    if (qEmpLst(i).ID == "A")
    {
    lstEmp.Add(qEmpLst(i).ID);
    continue;
    }
    i += 1;
    }
    Hiểu đơn giản khi remove bạn không tăng phần tử i là thành công

  7. #7
    Ngày gia nhập
    10 2009
    Nơi ở
    gầm cầu
    Bài viết
    156

    Trích dẫn Nguyên bản được gửi bởi toi_xau Xem bài viết
    Bạn dùng cách sau sẽ có thể xóa được. Bạn có thể linh động chuyển nó sang For đều được

    Code:
    while (i <= qEmpLst.Count - 1)
    {
    if (qEmpLst(i).ID == "A")
    {
    lstEmp.Add(qEmpLst(i).ID);
    continue;
    }
    i += 1;
    }
    Hiểu đơn giản khi remove bạn không tăng phần tử i là thành công
    cuộc sống mà ai chả muốn có sự đơn giản hóa vấn đề . nhưng mình đọc dòng code của bạn và ko hiểu nó có mục đích nào và giải quyết dc vấn đề gì ???

    1. mình chưa dc gặp kiểu mảng ( array hay List hay gần giống vậy ) cho phép truy cập đến thành viên của nó thông qua dấu ngoặc tròn () ??? bạn có giới thiệu cho mình qEmpLst là kiểu tập hợp nào ko ???

    2.dòng code của bạn theo như lý thuyết và thực tiễn mà mình biết sẽ giúp chương trình dc .... treo hay còn gọi là đơ . vì khi continue đặt ở chỗ đó thì 2 dk
    i <= qEmpLst.Count - 1

    qEmpLst(i).ID == "A"
    có lúc cùng dc thỏa mãn và vòng lặp dc chạy vô tận

    3.
    Hiểu đơn giản khi remove bạn không tăng phần tử i là thành công
    mình ko có cách gì hiểu dc lời này . ko biết nó đơn giản chỗ nào ???

  8. #8
    Ngày gia nhập
    08 2011
    Nơi ở
    Yên Bái- Hà Nội
    Bài viết
    961

    hi. Mình tò mò muốn hỏi chủ thớt. Bạn cứ cố dùng foreach để làm gì khi mà nó không khả thi? ngoài ra tốc độ của foreach =1/2 for
    Skype: mrfour.it - Yahoo:mrfour_it
    Gmail: mrfour.it@gmail.com
    Bạn muốn học lập trình? Bạn chưa có kiến thức cơ bản? Bạn muốn học từ cơ bản tới nâng cao?... Bạn muốn có source code để tham khảo? Muốn có người hỗ trợ khi học?....http://www.laptrinh123.com sẽ giúp bạn những điều đó!

  9. #9
    Ngày gia nhập
    10 2009
    Nơi ở
    gầm cầu
    Bài viết
    156

    Trích dẫn Nguyên bản được gửi bởi mrfour.it Xem bài viết
    hi. Mình tò mò muốn hỏi chủ thớt. Bạn cứ cố dùng foreach để làm gì khi mà nó không khả thi? ngoài ra tốc độ của foreach =1/2 for
    mình nghe nói chuyển sang dùng vòng lặp for sẽ hết lỗi và đúng là hết thật
    bạn nên đọc kĩ bài viết chỗ này . mình lập topic để chúng ta đc dịp thảo luận kinh nghiệm về sự khác nhau trong cách làm việc của 2 em For và Foreach .bạn nói tốc độ Foreach = 1/2 For thì bạn nên xem lại

    khi viết ct chỉ khi có nhu cầu muốn sử dụng số index của 1 thành viên trong tập hợp hoặc chỉ muốn duyệt qua 1 vài phần tử trong tập hợp hoặc cần gọi phương thức Add () hay Remove() người ta mới xài For . còn đâu để tối ưu tốc độ vẫn là nên xài Foreach
    cám ơn các bạn có thiện chí chia sẻ . mình chỉ ko thích những bạn vô trả lời topic của người khác kiểu ba xàm ba láp ko đi tới đâu .
    mình cũng chia sẻ luôn với các bạn rằng nếu muốn gọi phương thức remove trong vòng lặp Foreach vẫn có cách lách luật đàng hoàng chứ ko phải gọi phương thức Remove rồi gọi luôn break
    dưới đây là 1 thí dụ

    Visual C# Code:
    1. List <T> blackList = new List <T> ();
    2.             foreach (var v in danhsach) // danhsach và blackList có cùng kiểu dữ liệu thành viên
    3.             {
    4.                 if (v.tuoi ==1)
    5.                 {
    6.                     blackList.Add(v);
    7.                 }
    8.             }
    9.             foreach (var v in blackList)
    10.             {
    11.                 danhsach.Remove(v);
    12.             }

Các đề tài tương tự

  1. ADO.NET So sánh vòng lăp Foreach() với for() C#
    Gửi bởi moibietdi trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 11
    Bài viết cuối: 08-07-2013, 06:40 PM
  2. Repeater vẫn còn dữ liệu khi remove item cuối cùng trong list
    Gửi bởi huskygarcon trong diễn đàn Thắc mắc lập trình ASP.NET
    Trả lời: 1
    Bài viết cuối: 29-09-2011, 12:51 PM
  3. Remove các Item trong ListBox
    Gửi bởi Cloud Strife trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 14
    Bài viết cuối: 14-05-2011, 08:26 AM
  4. Làm sao để dừng vòng lặp(foreach) của một sự kiện bằng một sự kiện khác.
    Gửi bởi nguoirung1.6 trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 5
    Bài viết cuối: 26-12-2010, 05:04 PM
  5. vòng lặp foreach
    Gửi bởi khatmau90 trong diễn đàn Nhập môn lập trình C#, ASP.NET
    Trả lời: 3
    Bài viết cuối: 01-05-2010, 02:27 AM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn