C# Yield Return Statement (2024)

Thank you to our sponsors who keep this newsletter free to the reader:

Dotnetjobs is a reverse job board that empowers .NET developers available for their next job.Stop scouring traditional job boards and sit back as companies reach out to you first.

Sponsor this newsletter

In this week's newsletter I want to talk about the yield keyword in C#.I think it's a powerful C# feature and I wanted to highlight the benefits.

The yield keyword tells the compiler that the method in which it appearsis an iterator block. An iterator block, or method, returns an IEnumerableas the result. And the yield keyword is used to return the values for theIEnumerable.

An interesting thing aboug IEnumerable is that it is lazily evaluted.Calling a method with an iterator block doesn't run any code. It's onlywhen the IEnumerable is iterated over, or enumerated, that we getthe actual values. I'll talk about this more later.

Let's see how we can start using the yield keyword!

How To Use The Yield Keyword

The yield keyword on it's own doesn't do anything, you have to combineit with the return or break statement:

  • yield return - provides the next value of the iterator
  • yield-break - signals the end of iteration

In every project I worked on, there's a piece of code similar to thefollowing. You create a list to hold the results, add elements to thelist, and return the list in the end.

var engineers = GetSoftwareEngineers();public IEnumerable<SoftwareEngineer> GetSoftwareEngineers(){ var result = new List<SoftwareEngineer>(); for(var i = 0; i < 10; i++) { result.Add(new SoftwareEngineer { Id = i }); } return result;}

You can simplify the method using the yield return statement, andcompletely remove the intermediate list required to hold the results.

var engineers = GetSoftwareEngineers();public IEnumerable<SoftwareEngineer> GetSoftwareEngineers(){ for(var i = 0; i < 10; i++) { yield return new SoftwareEngineer { Id = i }; }}

However, it's important to note these two implementation are fundamentallydifferent from each other. In the first example, the entire list ispopulated and materialized. In the second example, the IEnumerablereturned will not be materialized and you have to either iterate overit inside a foreach loop or call ToList().

Stopping Iteration With Yield Break

You can use the yield break statement to stop iteration and exitthe iterator block. Typically you would do this when a certaincondition is met, or you only want to return a specific set of valuesfrom the iterator block.

Here's an example where this would be useful:

Console.WriteLine(string.Join(", ", TakeWhilePositive(new[] { 1, 2, -3, 4 })));// Output: 1, 2public IEnumerable<int> TakeWhilePositive(IEnumerable<int> numbers){ foreach(int num in numbers) { if (num > 0) { yield return num; } else { yield break; } }}

Working With IAsyncEnumerable

In C# 8 we got the IAsyncEnumerable type which allows us toiterate over a collection asynchronously with the yield statement.

For example, this can be useful when you want to call a thid-partyAPI multiple times to fetch some data. A common situation is whenyou get a list of users from the database, and then have to callan external storage service to get profile picture information.

Without IAsyncEnumerable you would have to do something like this:

public async Task<IEnumerable<User>> GetUsersAsync(){ var users = await GetUsersFromDbAsync(); foreach(var user in users) { user.ProfileImage = await GetProfileImageAsync(user.Id); } return users;}// And you would call the method like this.var users = await GetUsersAsync();foreach(var user in users){ Console.WriteLine(user);}

Now, consider this same example with the use of IAsyncEnumerable:

public async IAsyncEnumerable<User> GetUsersAsync(){ var users = await GetUsersFromDbAsync(); foreach(var user in users) { user.ProfileImage = await GetProfileImageAsync(user.Id); yield return user; }}// And you would call the method like this.await foreach(var user in GetUsersAsync()){ Console.WriteLine(user);}

The second implementation will iterate over the users returned fromthe database when they are yielded by the IAsyncEnumerable.

When Should I Use Yield?

I've found a few interesting practical applications for the yield keyword.One example is when implementing Domain-Driven Design value objects.

Value objects need to support structural equality. They need to implementa method that returns all of the equality components. Here's an example ofthat using the yield return statement:

public class Address{ public string City { get; init; } public string Street { get; init; } public string Zip { get; init; } public string Country { get; init; } public IEnumerable<object> GetEqualityComponents() { yield return City; yield return Street; yield return Zip; yield return Country; }}
C# Yield Return Statement (2024)
Top Articles
Latest Posts
Article information

Author: Corie Satterfield

Last Updated:

Views: 6689

Rating: 4.1 / 5 (42 voted)

Reviews: 89% of readers found this page helpful

Author information

Name: Corie Satterfield

Birthday: 1992-08-19

Address: 850 Benjamin Bridge, Dickinsonchester, CO 68572-0542

Phone: +26813599986666

Job: Sales Manager

Hobby: Table tennis, Soapmaking, Flower arranging, amateur radio, Rock climbing, scrapbook, Horseback riding

Introduction: My name is Corie Satterfield, I am a fancy, perfect, spotless, quaint, fantastic, funny, lucky person who loves writing and wants to share my knowledge and understanding with you.