yield
Brug af yield
i C# er en kraftfuld funktion, der tillader udviklere at arbejde med sekvenser af data på en effektiv og nem måde. yield
bruges inden i en iterator block til at give en værdi tilbages til den kode, der forbruger iteratoren, hver gang den kaldes, uden at miste staten mellem iterationerne. Dette gør det muligt at skabe komplekse iterationsscenarier, som f.eks. late evaluation (udvurdering efter behov) og stateful iteration, med relativt enkle og læsbare kodekonstruktioner.
Intro til yield
yield
er et nøgleord i C#, som bruges til at returnere hvert element et ad gangen fra en iterator metode. En iterator metode er en metode, der returnerer et af to interfaces: IEnumerable
eller IEnumerator
, afhængigt af om den returnerer en sekvens af værdier eller en enumerator, der kan iterere gennem en sekvens.
For at bruge yield
i din C# kode, skal du følge disse trin:
-
Opret en metode, der returnerer
IEnumerable
ellerIEnumerator
. Denne metode vil indeholde din iteration logik. -
Brug
yield return
inde i metoden for at returnere det næste element i sekvensen. Hver gang metoden kaldes af forbrugeren, fortsætter den fra det punkt, hvor den sidst brugteyield return
, hvilket gør det muligt at gemme staten mellem iterationerne. -
(Valgfrit) Brug
yield break
for at afslutte iterationen tidligt. Dette er nyttigt, hvis der er en betingelse, der gør, at du ikke ønsker at fortsætte med at returnere elementer.
Eksempel på brug af yield
foreach (int i in GetPowersOfTwoWithoutYield(5))
{
Console.WriteLine(i); // *, *, *, *, *, 1, 2, 4, 8, 16
}
foreach (int i in GetPowersOfTwoWithYield(5))
{
Console.WriteLine(i); // *, 1, *, 2, *, 4, *, 8, *, 16
}
IEnumerable<int> GetPowersOfTwoWithoutYield(int n)
{
List<int> result = new List<int>();
int value = 1;
for (int i = 0; i < n; i++)
{
result.Add(value);
value = value * 2;
Console.WriteLine("*");
}
return result;
}
IEnumerable<int> GetPowersOfTwoWithYield(int n)
{
int result = 1;
for (int i = 0; i < n; i++)
{
Console.WriteLine("*");
yield return result;
result = result * 2;
}
}
I dette eksempel returnerer metoderne de første n
potenser af 2. Den første metode, GetPowersOfTwoWithoutYield
, bruger en List<int>
til at gemme resultaterne og returnerer listen, når iterationen er færdig. Den anden metode, GetPowersOfTwoWithYield
, bruger yield return
til at returnere hvert resultat en ad gangen. Bemærk, at der er en Console.WriteLine("*");
i begge metoder.
Når du kører dette eksempel, vil du se, at GetPowersOfTwoWithoutYield
udskriver *
fem gange, før den returnerer resultaterne, mens GetPowersOfTwoWithYield
udskriver *
og returnerer resultaterne en ad gangen. Dette viser, hvordan yield
returnerer resultaterne efter behov og gemmer staten mellem iterationerne.
Slutteligt et lidt mere komplekst eksempel med brug af en nedarvet klasse:
class Person
{
public string Navn { get; set; }
public int Alder { get; set; }
}
class Personer : IEnumerable<Person>
{
private List<Person> _personer = new List<Person>();
public IEnumerator<Person> GetEnumerator()
{
return ((IEnumerable<Person>)_personer).GetEnumerator();
}
public void TilføjPerson(Person p)
{
_personer.Add(p);
}
public IEnumerable<Person> FindAllePersoner()
{
foreach (var p in _personer)
yield return p;
}
public IEnumerable<Person> FindPersonerUnderAlder(int alder)
{
foreach (var p in _personer)
if (p.Alder < alder)
yield return p;
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<Person>)_personer).GetEnumerator();
}
}
Fordele ved at bruge yield
- Forbedret performance og hukommelsesbrug: Da elementerne genereres efter behov, bruges hukommelsen mere effektivt, og der er ikke behov for at oprette store samlinger op forhånd.
- Simpel kode for komplekse iterationer:
yield
gør det nemmere at implementere komplekse iterationsscenarier uden at skulle skrive kompleks kode for at håndtere iterationens tilstand.
Brug af yield
i C# er en meget nyttig mekanisme til at arbejde med sekvenser af data på en måde, der er både hukommelseseffektiv og let at kode. Ved at tillade lazy evaluation og simplificere komplekse iterationer, kan yield
gøre din kode både mere læsbar og effektiv. Uanset om du arbejder med store datasæt eller komplekse forretningslogikker, kan yield
være et værdifuldt værktøj i din C# værktøjskasse.