ประเภทของคลาสforeach
ใดบ้างที่สามารถใช้ลูปได้?
ประเภทของคลาสforeach
ใดบ้างที่สามารถใช้ลูปได้?
คำตอบ:
จริงๆแล้วพูดอย่างเคร่งครัดสิ่งที่คุณต้องใช้foreach
คือGetEnumerator()
วิธีสาธารณะที่ส่งคืนบางสิ่งด้วยbool MoveNext()
วิธีการและ? Current {get;}
คุณสมบัติ แต่ส่วนใหญ่ที่พบความหมายของนี้คือ "สิ่งที่ดำเนินการIEnumerable
/ IEnumerable<T>
กลับ/IEnumerator
IEnumerator<T>
โดยปริยายนี้รวมถึงสิ่งที่ดำเนินการICollection
/ ICollection<T>
เช่นอะไรเช่นCollection<T>
, List<T>
อาร์เรย์ ( T[]
) ฯลฯ ดังนั้น "การเก็บรวบรวมข้อมูล" มาตรฐานใด ๆ foreach
โดยทั่วไปจะสนับสนุน
สำหรับการพิสูจน์จุดแรกสิ่งต่อไปนี้ใช้ได้ดี:
using System;
class Foo {
public int Current { get; private set; }
private int step;
public bool MoveNext() {
if (step >= 5) return false;
Current = step++;
return true;
}
}
class Bar {
public Foo GetEnumerator() { return new Foo(); }
}
static class Program {
static void Main() {
Bar bar = new Bar();
foreach (int item in bar) {
Console.WriteLine(item);
}
}
}
มันทำงานอย่างไร?
foreach loop เช่นforeach(int i in obj) {...}
kinda เท่ากับ:
var tmp = obj.GetEnumerator();
int i; // up to C# 4.0
while(tmp.MoveNext()) {
int i; // C# 5.0
i = tmp.Current;
{...} // your code
}
อย่างไรก็ตามมีรูปแบบต่างๆ ตัวอย่างเช่นหาก enumerator (tmp) รองรับIDisposable
ก็จะใช้ด้วย (คล้ายกับusing
)
สังเกตความแตกต่างของตำแหน่งของการประกาศ " int i
" ภายใน (C # 5.0) กับภายนอก (ขึ้น C # 4.0) ของลูป เป็นสิ่งสำคัญหากคุณใช้i
ในวิธีการแบบไม่ระบุตัวตน / แลมบ์ดาภายในโค้ดบล็อกของคุณ แต่นั่นก็เป็นอีกเรื่องหนึ่ง ;-p
for-loop
(คุณจะเห็นสิ่งนี้เมื่อทำงานกับ IL)
จากMSDN :
foreach
คำสั่งซ้ำกลุ่มของงบที่ฝังตัวสำหรับแต่ละองค์ประกอบในอาร์เรย์หรือการเก็บรวบรวมวัตถุforeach
คำสั่งที่ใช้ในการย้ำผ่านคอลเลกชันที่จะได้รับข้อมูลที่ต้องการ แต่ไม่ควรนำมาใช้เพื่อเปลี่ยนเนื้อหาของคอลเลกชันที่จะหลีกเลี่ยงผลข้างเคียงที่คาดเดาไม่ได้ (เน้นของฉัน)
ดังนั้นหากคุณมีอาร์เรย์คุณสามารถใช้คำสั่ง foreach เพื่อวนซ้ำผ่านอาร์เรย์ได้ดังนี้:
int[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 };
foreach (int i in fibarray)
{
System.Console.WriteLine(i);
}
คุณยังสามารถใช้เพื่อวนซ้ำผ่านList<T>
คอลเลคชันได้เช่น:
List<string> list = new List<string>();
foreach (string item in list)
{
Console.WriteLine(item);
}
ตามบล็อกโพสต์Duck Notationใช้การพิมพ์เป็ด
นี่คือเอกสาร: บทความหลักเกี่ยว กับ Arrays With Collection Objects
โปรดทราบว่า "ประเภทขององค์ประกอบคอลเลกชันต้องสามารถแปลงเป็นประเภทตัวระบุได้" บางครั้งไม่สามารถตรวจสอบได้ในเวลาคอมไพล์และสามารถสร้างข้อยกเว้นรันไทม์ได้หากไม่สามารถกำหนดประเภทอินสแตนซ์ให้กับประเภทการอ้างอิง
สิ่งนี้จะสร้างข้อยกเว้นรันไทม์หากไม่มี Apple อยู่ในตะกร้าผลไม้เช่นส้ม
List<Fruit> fruitBasket = new List<Fruit>() { new Apple(), new Orange() };
foreach(Apple a in fruitBasket)
สิ่งนี้กรองรายการได้อย่างปลอดภัยเฉพาะแอปเปิ้ลโดยใช้Enumerable.OfType
foreach(Apple a in fruitBasket.OfType<Apple>() )
IList<ListItem> illi = new List<ListItem>();
ListItem li = null;
foreach (HroCategory value in listddlsubcategory)
{
listddlsubcategoryext = server.getObjectListByColumn(typeof(HroCategory), "Parentid", value.Id);
li = new ListItem();
li.Text = value.Description;
li.Value = value.Id.ToString();
illi.Add(li);
IList<ListItem> newilli = new List<ListItem>();
newilli = SubCatagoryFunction(listddlsubcategoryext, "-->");
foreach (ListItem c in newilli)
{
illi.Add(c);
}
}
ข้อมูลที่เป็นประโยชน์เกี่ยวกับเรื่องนี้สามารถพบได้ในMSDNด้วย นำสาระสำคัญจากบทความนั้น:
คีย์เวิร์ด foreach จะระบุคอลเล็กชันโดยเรียกใช้คำสั่งฝังตัวหนึ่งครั้งสำหรับแต่ละองค์ประกอบในคอลเลกชัน:
foreach (var item in collection)
{
Console.WriteLine(item.ToString());
}
คอมไพเลอร์แปล foreach loop ที่แสดงในตัวอย่างด้านบนเป็นสิ่งที่คล้ายกับโครงสร้างนี้:
IEnumerator<int> enumerator = collection.GetEnumerator();
while (enumerator.MoveNext())
{
var item = enumerator.Current;
Console.WriteLine(item.ToString());
}
คุณสามารถลองสิ่งนี้ ...
List<int> numbers = new List<int>();
numbers.Add(5);
numbers.Add(15);
numbers.Add(25);
numbers.Add(35);
Console.WriteLine("You are added total number: {0}",numbers.Count);
foreach (int number in numbers)
{
Console.WriteLine("Your adding Number are: {0}", number);
}