// Chapter 10 // Functional Programming /* * 1. Immutability > when no change is needed in the state of the object ex. tuples * 2. Pure Functions > no side effect on the return "you have the same output given the input * 3. High Order Functions > functions that are passed as args * 4. Lambda Expression > one operation or exp assigned * 5. LINQ - standardized query syntax * */ // using statement using System; // core C# library using System.Linq; // LINQ // CreditCardProcessing Class public class CreditCardProcessing { // Immutable CreditCard class public class CreditCard { public string CardNumber { get; } public string ExpiryDate { get; } public string Cvc { get; } public CreditCard(string cardNumber, string expiryDate, string cvc) { CardNumber = cardNumber; ExpiryDate = expiryDate; Cvc = cvc; } } // Immutable CreditCard Class // Function to process the credit card public static IEnumerable ProcessCreditCards(IEnumerable creditCards) { // foreach loop structural // foreach loop, that happens AFTER you call the function to loop thru the tuples is being replaced with an Enumerator the happens WHILE the function is being initialized. // here we have already prepped the data // enumerator functional iterator // LINQ where() to validate the credit card info // Option 1 for LINQ High Order Function /* * var validCards = creditCards.Where(isCreditCardValid); */ // Option 2 for LINQ Lambda Expression "Arrow Function" var validCards = creditCards.Where( // Lambda Exp (params) => exp or op; (card) => !string.IsNullOrEmpty(card.CardNumber) && !string.IsNullOrEmpty(card.ExpiryDate) && !string.IsNullOrWhiteSpace(card.Cvc) ); // where return validCards; // return does not change } // ProcessCreditCards // boolean pure function to validate the credit card / use in the Where() LINQ statment // naming with an is prefix for bool > best practice public static bool isCreditCardValid(CreditCard card) { // do something to validate // card # has to be 16 digits // exp date is in mm/yy format // etc. // check for nulls // LINQ IsNullOrEmpty() built in query to check for nulls or empty or whitespace return !string.IsNullOrEmpty(card.CardNumber) && !string.IsNullOrEmpty(card.ExpiryDate) && !string.IsNullOrWhiteSpace(card.Cvc); // return true for valid cards } // isCreditCardValid } // CreditCardProcessing Class // Program Class class Program { static void Main(string[] args) { // Instances of Credit Cards var creditCards = new List { new CreditCardProcessing.CreditCard("", "12/25", "123"), // false new CreditCardProcessing.CreditCard("4444111122223333", "11/28", "123"), // true new CreditCardProcessing.CreditCard("","",""), // false new CreditCardProcessing.CreditCard("4444111122225555", "11/28", "123") //true }; // List of Credit Cards // use a foreach to loop thru the list and vaildate var validCards = CreditCardProcessing.ProcessCreditCards(creditCards); // List foreach (var creditCard in validCards) // true { // scope local var creditCard Console.WriteLine($"Valid Credit Card: {creditCard.CardNumber}, Expiration Date: {creditCard.ExpiryDate}, Security Code: {creditCard.Cvc}."); } // foreach } // Main } // Program Class