yield (C# Başvurusu)
Bir deyiminde yield bağlamsal anahtar sözcüğünü kullanırken, göründüğü yöntemin, işlecin veya erişimcinin birerator get olduğunu belirtebilirsiniz. bir tekrarlayıcı tanımlamak için kullanmak, özel bir koleksiyon türü için ve desenini uygulayan açık bir ek sınıf (bir numaralamanın durumunu tutan sınıf, örneğin bkz. yield IEnumerator<T> ) IEnumerable IEnumerator gereklerini ortadan kaldırır.
Aşağıdaki örnekte deyiminin iki formu yield gösterir.
yield return <expression>;
yield break;
Açıklamalar
Her öğeyi yield return tek tek dönmek için deyimini kullanırsiniz.
Bir tekrarlayıcı yönteminden döndürülen sıra bir foreach deyimi veya LINQ sorgusu kullanılarak tüketilebilir. Döngülerin her foreach yinelemesi, yineleme yöntemini çağrılır. Bir yield return deyimine tekrarlayıcı yönteminde ulaşıldı, expression döndürülür ve kodda geçerli konum korunur. Yürütme, yineleyici işlevinin bir sonraki çağrılmasında bu konumdan başlar.
Tekrarlayıcı bir döndürünce, bu sıra bir System.Collections.Generic.IAsyncEnumerable<T> await foreach deyimi kullanılarak zaman uyumsuz olarak tüketilebilir. Döngü yinelemesi deyimine foreach benzer. Aradaki fark, bir sonraki öğe için ifadeyi döndürmeden önce her yinelemenin zaman uyumsuz bir işlem için askıya alınarak askıya alınabilir olmasıdır.
Yinelemeyi sona yield break ererken deyimini kullanabilirsiniz.
Tekrarlayıcılar hakkında daha fazla bilgi için bkz. Tekrarlayıcılar.
Iterator yöntemleri ve erişimcileri al
Bir yineleyicinin bildirimi aşağıdaki gerekliliklerle uyuşmalıdır:
- Dönüş türü aşağıdaki türlerden biri olması gerekir:
- Bildirimin , ref veya out parametrelerinde herhangi bir değeri yok.
veya yield döndüren bir tekrarlayıcının IEnumerable IEnumerator object türü. Tekrarlayıcı veya döndürürse, deyiminde ifadenin türünden genel tür IEnumerable<T> IEnumerator<T> parametresine örtülü yield return bir dönüştürme olmalıdır.
Bir veya deyimini yield return şu özelliklere yield break dahil etmek için:
- Lambda ifadeleri ve anonim yöntemleri.
- Güvenli olmayan bloklar içeren yöntemler. Daha fazla bilgi için bkz. güvenli değil.
Özel durum işleme
deyimi yield return bir try-catch bloğunda yer alamz. Deyimi, yield return try-finally deyiminin try bloğunda yer alıyor olabilir.
Deyimi yield break bir try bloğunda veya yakalama bloğunda yer alıyor olabilir, ancak finally bloğunda yer alamz.
veya gövdesi (iterator yönteminin dışında) bir özel durum foreach oluşturursa, await foreach finally iterator yönteminde bir blok yürütülür.
Teknik uygulama
Aşağıdaki kod bir IEnumerable<string> yineleyici yönteminden bir döndürür ve ardından öğelerinde yineler.
IEnumerable<string> elements = MyIteratorMethod();
foreach (string element in elements)
{
...
}
çağrısı MyIteratorMethod yönteminin gövdesinde yürütülmez. Bunun yerine çağrısı IEnumerable<string> değişkenine elements bir döndürür.
Döngü yinelemesinde foreach yöntemi MoveNext için çağrılır. elements Bu çağrı, bir sonraki MyIteratorMethod deyime ulaşıncaya yield return kadar gövdeyi yürütür. deyimi tarafından döndürülen ifade yalnızca döngü gövdesi tarafından tüketilmek üzere değişkenin değerini değil, aynı zamanda bir yield return element olan özelliğini de Current elements IEnumerable<string> belirler.
Döngüyü izleyen her yinelemede yineleyici gövdesinin yürütülmesi, deyimine ulaştığında tekrar durdurularak geriye doğru foreach devam yield return eder. Döngü, foreach tekrarlayıcı yönteminin veya deyiminin sonuna yield break ulaşıldıklarda tamamlanır.
Aşağıdaki kod bir IAsyncEnumerable<string> yineleyici yönteminden bir döndürür ve ardından öğelerinde yineler.
IAsyncEnumerable<string> elements = MyAsyncIteratorMethod();
await foreach (string element in elements)
{
// ...
}
Döngü yinelemesinde await foreach yöntemi IAsyncEnumerator<T>.MoveNextAsync için çağrılır. elements System.Threading.Tasks.ValueTask<TResult>bir MoveNext sonrakine ulaşıldıklarına göre yield return dönüş tamamlanır.
Döngüyü izleyen her yinelemede yineleyici gövdesinin yürütülmesi, deyimine ulaştığında tekrar durdurularak geriye doğru await foreach devam yield return eder. Döngü, await foreach tekrarlayıcı yönteminin veya deyiminin sonuna yield break ulaşıldıklarda tamamlanır.
Örnekler
Aşağıdaki örnekte döngü yield return içinde yer alan bir deyimi for vardır. yönteminde deyim foreach gövdesinin her Main yinelemesi, tekrarlayıcı Power işlevine bir çağrı oluşturur. Yineleme işlevine yapılan her çağrı, döngüyü bir sonraki yinelemesinde oluşan yield return deyiminin sonraki yürütme işlemine for devam eder.
Bir tekrarlayıcı arabirim türü olan, IEnumerable tekrarlayıcı yönteminin dönüş türü olur. Yineleyici yöntem çağrıldığında, bir sayının kuvvetlerini içeren sayılabilir bir nesne döndürür.
public class PowersOf2
{
static void Main()
{
// Display powers of 2 up to the exponent of 8:
foreach (int i in Power(2, 8))
{
Console.Write("{0} ", i);
}
}
public static System.Collections.Generic.IEnumerable<int> Power(int number, int exponent)
{
int result = 1;
for (int i = 0; i < exponent; i++)
{
result = result * number;
yield return result;
}
}
// Output: 2 4 8 16 32 64 128 256
}
Aşağıdaki örnek, bir get iterator olan bir erişimciyi gösteriyor. Örnekte, her deyim yield return kullanıcı tanımlı bir sınıfın örneğini döndürür.
public static class GalaxyClass
{
public static void ShowGalaxies()
{
var theGalaxies = new Galaxies();
foreach (Galaxy theGalaxy in theGalaxies.NextGalaxy)
{
Debug.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears.ToString());
}
}
public class Galaxies
{
public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy
{
get
{
yield return new Galaxy { Name = "Tadpole", MegaLightYears = 400 };
yield return new Galaxy { Name = "Pinwheel", MegaLightYears = 25 };
yield return new Galaxy { Name = "Milky Way", MegaLightYears = 0 };
yield return new Galaxy { Name = "Andromeda", MegaLightYears = 3 };
}
}
}
public class Galaxy
{
public String Name { get; set; }
public int MegaLightYears { get; set; }
}
}
C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.