using System.Collections.Generic;
static void Main(string[] args)
var popcornBags = new List<PopcornBag>(){
new PopcornBag{ Type = PopcornBagType.Bland },
new PopcornBag{ Type = PopcornBagType.Bland },
new PopcornBag{ Type = PopcornBagType.WithSugar },
new PopcornBag{ Type = PopcornBagType.WithSalt },
new PopcornBag{ Type = PopcornBagType.WithButter },
new PopcornBag{ Type = PopcornBagType.WithButter },
new PopcornBag{ Type = PopcornBagType.WithButter }
Console.WriteLine("Main Program: This is immediate execution and the entire data source will be accessed to apply this filter at the momment this call is made.\n");
var allButterPopCornBags = popcornBags.immediateFilterBag(b => b.Type == PopcornBagType.WithButter);
Console.WriteLine("Main Program: The immediate filter bag executed and went through the entire data source to do his things... he is always so eager to work... But I really don't need this data for anything, what a waste of time.\n\n");
Console.WriteLine("Main Program: This is deferred execution and the data source will only be accessed when the code as the need to 'see' what's in the data source.\n");
var allBlandPopCornBags = popcornBags.deferredFilterBag(b => b.Type == PopcornBagType.Bland);
Console.WriteLine("Main Program: While I don't need to show or work with the data, the deferred method won't do any work... He's so lazy, but at least is saving me some time and memory.\n");
Console.WriteLine("Main Program: Should we do it now?... Ok, we have waited long enough... Let's let the method work already...\n\n");
foreach(var bag in allBlandPopCornBags)
Console.WriteLine($"Main Program: We have a match and it's bland... But why do we all need to be special anyway?\n");
Console.WriteLine("\nMain Program: So yeah... this is it, this is where we say goodbye. Return 0;\n\n");
public class PopcornBag {
private PopcornBagType _type;
public PopcornBagType Type {
Console.WriteLine($"PopcornBag Entity: I'm a bag of {_type.ToString()} popcorn.");
public enum PopcornBagType {
public static class PopcornBagExtensions {
public static IEnumerable<T> immediateFilterBag<T>(this IEnumerable<T> source, Func<T, bool> predicate) where T : PopcornBag
var result = new List<T>();
foreach(var item in source){
public static IEnumerable<T> deferredFilterBag<T>(this IEnumerable<T> source, Func<T, bool> predicate) where T : PopcornBag
foreach(var item in source){
Console.WriteLine("Deferred Filter: Ughh, a matching element... I guess I will let them know... I hope he doesn't ask for anything again... No way I'm going through that entire list of things If I can avoid it!\n");
Console.WriteLine("Deferred Filter: Ughh a new request... Ok I guess I will continue from where I left... Here we go again!\n");
Console.WriteLine($"\nDeferred Filter: Well I guess there's nothing else to see here... byeeee!\n");