yield
permits to return a part of a result in a executing loop.
Please look at the following code that does not uses yield
:
foreach cFile as string in GetFiles( "c:\" ) WriteLine( cFile ) next return function GetFiles( cFolder as string ) as List<string> local aFiles as string[] local oFiles as List<string> WriteLine( "start creating list" ) oFiles := List<string>{} aFiles := Directory.GetFiles( cFolder ) foreach cFile as string in aFiles oFiles:Add( cFile ) next WriteLine( "end creating list" ) return oFiles
As you would expect, this code shows the follwing output:
start creating list end creating list c:\bootmgr c:\BOOTNXT c:\bootTel.dat c:\hiberfil.sys c:\lang.txt c:\pagefile.sys c:\swapfile.sys
If you change the code to use yield, you need to change the type of your function - and your function cannot more have any return
statement:
foreach cFile as string in GetFiles( "c:\" ) WriteLine( cFile ) next function GetFiles( cFolder as string ) as IEnumerable<string> local aFiles as string[] local oFiles as List<string> WriteLine( "start creating list" ) oFiles := List<string>{} aFiles := Directory.GetFiles( cFolder ) foreach cFile as string in aFiles yield return cFile next WriteLine( "end creating list" )
This code produces the following output (please note that the output is created by the calling function before the called function is finished!):
start creating list c:\bootmgr c:\BOOTNXT c:\bootTel.dat c:\hiberfil.sys c:\lang.txt c:\pagefile.sys c:\swapfile.sys end creating list
To explain a bit more: the yield
returns the member of the list, and the calling code can work immediatly with instead of waiting for the called function to be complete.
This is particularly useful if you have longer processes and need to refresh the user interface.