Hangi tür sınıflar foreachdöngüleri kullanabilir ?
Yanıtlar:
Aslında, kesinlikle konuşursak, kullanmanız gereken tek şey, bir yöntem ve bir özellik ile bir şey döndüren foreachhalka açık GetEnumerator()bir bool MoveNext()yöntemdir ? Current {get;}. Ancak, en yaygın Bunun anlamı uygular o şey" olduğunu IEnumerable/ IEnumerable<T>bir dönen IEnumerator/ IEnumerator<T>.
Dolayısı ile , bu , diziler ( ), vb. Gibi ICollection/ uygulayan her şeyi içerir . Dolayısıyla, herhangi bir standart "veri koleksiyonu" genellikle destekleyecektir .ICollection<T>Collection<T>List<T>T[]foreach
İlk noktanın kanıtı için, aşağıdakiler gayet iyi çalışıyor:
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);
}
}
}
O nasıl çalışır?
Bir foreach(int i in obj) {...}tür foreach döngüsü şuna eşittir:
var tmp = obj.GetEnumerator();
int i; // up to C# 4.0
while(tmp.MoveNext()) {
int i; // C# 5.0
i = tmp.Current;
{...} // your code
}
Ancak, farklılıklar var. Örneğin, numaralandırıcı (tmp) destekliyorsa IDisposable, o da kullanılır (benzer using).
Döngünün " int i" içinde (C # 5.0) ile dışında (C # 4.0'a kadar ) bildiriminin yerleştirilmesindeki farklılığa dikkat edin. iKod bloğunuzun içinde anonim bir yöntem / lambda kullanıyorsanız önemlidir . Ama bu başka bir hikaye ;-p
for-loop(IL ile çalışırken bunu görebilirsiniz).
Gönderen MSDN :
foreachTablosu her bir eleman için gömülü bir ifade grubunu tekrar bir dizi veya bir amacı, toplama .foreachİfadesi istenen bilgileri almak için topluluk içinde yineleme için kullanılır, ancak öngörülemeyen yan etkilerden kaçınmak için koleksiyonun içeriğini değiştirmek için kullanılmamalıdır. (vurgu benim)
Dolayısıyla, bir diziniz varsa, dizi boyunca yinelemek için foreach ifadesini kullanabilirsiniz, örneğin:
int[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 };
foreach (int i in fibarray)
{
System.Console.WriteLine(i);
}
Bunu bir List<T>koleksiyonda yinelemek için de kullanabilirsiniz , örneğin:
List<string> list = new List<string>();
foreach (string item in list)
{
Console.WriteLine(item);
}
Duck Notation adlı blog gönderisine göre , ördek yazımı kullanılıyor.
İşte belgeler: Koleksiyon Nesneli Dizilerle Ana makale
"Koleksiyon öğesinin türünün tanımlayıcı türüne dönüştürülebilir olması gerektiğine" dikkat etmek önemlidir. Bu bazen derleme zamanında kontrol edilemez ve örnek tipi referans tipine atanamazsa bir çalışma zamanı istisnası oluşturabilir.
Meyve sepetinde portakal gibi Apple olmayan bir ürün varsa, bu bir çalışma zamanı istisnası oluşturur.
List<Fruit> fruitBasket = new List<Fruit>() { new Apple(), new Orange() };
foreach(Apple a in fruitBasket)
Bu, listeyi yalnızca Enumerable.OfType kullanarak güvenli bir şekilde filtreler.
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);
}
}
Bu konuyla ilgili faydalı bilgiler MSDN'de de bulunabilir. O makalenin özünü almak:
Foreach anahtar sözcüğü, koleksiyondaki her öğe için gömülü ifadeyi bir kez çalıştırarak bir koleksiyonu numaralandırır:
foreach (var item in collection)
{
Console.WriteLine(item.ToString());
}
Derleyici, yukarıdaki örnekte gösterilen foreach döngüsünü bu yapıya benzer bir şeye çevirir:
IEnumerator<int> enumerator = collection.GetEnumerator();
while (enumerator.MoveNext())
{
var item = enumerator.Current;
Console.WriteLine(item.ToString());
}
bunu deneyebilirsin ...
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);
}