21

Can you help me in understanding of yield keyword in asp .NET(C#).

RBT
  • 24,161
  • 21
  • 159
  • 240
Vijjendra
  • 24,223
  • 12
  • 60
  • 92
  • Related post - [What is the yield keyword used for in C#?](https://stackoverflow.com/q/39476/465053) – RBT Apr 07 '18 at 11:34

5 Answers5

16

Yield return automatically creates an enumerator for you.

http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx

So you can do something like

//pseudo code:

while(get_next_record_from_database)
{
  yield return your_next_record;
}

It allows you to quickly create an object collection (an Enumerator) that you can loop through and retrieve records. The yield return statement handles all the of the code needed to create an enumerator for you.

The big part of the yield return statement is that you don't have to load all the of the items in a collection before returning the collection to the calling method. It allows lazy loading of the collection, so you don't pay the access penalty all at once.

When to use Yield Return.

Community
  • 1
  • 1
kemiller2002
  • 113,795
  • 27
  • 197
  • 251
6

Yield is much more than syntatic sugar or easy ways to create IEnumerables.

For more information I'd check out Justin Etherage's blog which has a great article explaining more advanced usages of yield.

John Farrell
  • 24,673
  • 10
  • 77
  • 110
  • Absolutely. You cannot fully appreciate `yield` until you understand exactly how it is creating the state machine for you. It is incredibly powerful. – Brian Gideon Jul 07 '10 at 13:54
  • Damn thats helpful. I know this is old but that post really did it for me. – Terrance Aug 12 '10 at 14:37
1

yield is used as syntactic sugar to return an IEnumerable<T> or IEnumerator<T> object from a method without having to implement your own class implementing these interfaces.

spoulson
  • 21,335
  • 15
  • 77
  • 102
  • Yes, because it is different from creating the IEnumerable yourself and returning it. – Jouke van der Maas Jul 07 '10 at 13:50
  • 2
    If you examine the MSIL using .NET Reflector, you can see that C# creates a hidden class implementing `IEnumerable` that is fed by `yield return` statements. So, at a high level, it is not different than implementing your own `IEnumerable` class, instantiating and returning it. – spoulson Jul 07 '10 at 13:56
  • Because calling yield "syntactic sugar" doesn't encompass its true potential. Your answer is harmful. What if somebody walks away after reading this and says "I won't use yield, its just syntactic sugar" – John Farrell Jul 07 '10 at 15:02
0

yield allows you to emit an IEnumerable where you'd normally return a more concrete type (like an IList).

This is a pretty good example of how it can simplify your code and clarify your intent. As for where you'd use it, anywhere on your pages that you need to iterate over a collection you could potentially use a method that returns an IEnumerable in place of a List/Dictionary/etc.

48klocs
  • 6,073
  • 3
  • 27
  • 34
0

I don't think the "Benefits" of using Stop and Continue pattern (AKA yield/enumerators), has been properly expounded upon. So let me try.

Say you have an app that needs to return 1 million records from the database. You have a few common practices:

  1. You could return a collection with 1 million objects like a List or Array, but that would lead to a huge amount of memory pressure and potentially the dreaded OutOfMemoryException.
  2. You could paginate 1,000 records at a time, but this too has its draw backs as you now have to write pagination logic
  3. You could serialize these objects to a file like JSON or other (this has to be the worst idea I've ever seen implemented)
  4. You should use the "yield" pattern; which in contrast to the other options is more like streaming objects

By using the yield pattern, you only hydrate one object at a time into memory. Furthermore, the consumption of objects is controlled by the code iterating through the IEnumerator/IEnumerable code. This should be a typical foreach code block.

Here is an example to contrast the code differences

/// Bad Deadpool...
List<MyDbRecord> GetData(int page, int pageSize) {
   using (var con = new DbContext()) {
      // Option 1: Straight object grabbing
      // return con.MyDbRecordSet.ToList();
      // Option 2: Pagination Example
      return con.MyDbRecordSet.Skip(page * pageSize).Take(pageSize).ToList();
      // Option 3: DON'T TRY THIS AT HOME!
      // var allTheRecords = con.MyDbRecordSet.ToList(); // Memory pressure
      // System.IO.File.WriteAllText(
      //    "C:\\Windows\\Temp\\temp.json",
      //    JsonConvert.SerializeObject(allTheRecords)
      // );// Large JSON Object dropped
   }
}

/// Bad Deadpool...
IEnumerable<MyDbRecord> GetData(int page, int pageSize) {
   using (var con = new DbContext()) {
      // Option 1: Straight object grabbing
      // return con.MyDbRecordSet.ToList();
      // Option 2: Pagination Example
      //return con.MyDbRecordSet.Skip(page * pageSize).Take(pageSize).ToList();
      // Option 3: DON'T TRY THIS AT HOME!
      // var allTheRecords = con.MyDbRecordSet.ToList(); // Memory pressure
      // System.IO.File.WriteAllText(
      //    "C:\\Windows\\Temp\\temp.json",
      //    JsonConvert.SerializeObject(allTheRecords)
      // );// Large JSON Object dropped
      foreach (var i in con.MyDbRecordSet.AsNoTracking().AsQueryable()) {
          yield return i; // Stream it vs buffering
      }
   }
}
RashadRivera
  • 793
  • 10
  • 17