When you loop over a list using foreach, you are using the Iterator Pattern. While most developers just use it, Senior Developers use the yield keyword to create memory-efficient data streams that only process one item at a time.
Normally, if a method returns a List<User>, it must first load all 10,000 users into the web server's RAM. With yield return, you create a "State Machine" that only generates the next item when requested.
// ❌ MEMORY HEAVY: Must load the entire file into RAM first
public List<string> GetLines() { ... return list; }
// ✅ MEMORY LIGHT: Streams lines one-by-one from the disk!
public IEnumerable<string> GetLinesStreamed()
{
foreach(var line in File.ReadLines("bigfile.txt"))
{
yield return line;
}
}
When you call a method with yield, no code actually runs. The code only begins executing when the human starts their foreach loop. This is the foundation of LINQ.
You can use yield break; to terminate a stream prematurely based on a condition, mimicking a break inside a loop but at the producer level.
Q: "Can I use 'yield' inside a try-catch block?"
Architect Answer: "You CANNOT use `yield` inside a `try-catch` block, but you CAN use it inside a `try-finally` block. This is because a `yield` statement suspends execution; the compiler generates a complex state machine behind the scenes. If an exception occurred while the method was 'paused' between yields, the CLR wouldn't know how to correctly re-enter the catch block. This is a common point of frustration for juniors, but the solution is simple: perform your error-prone work outside the yield loop or wrap the calling code in the try-catch instead."