static void Main(string[] args) { #region === ESERCITAZIONE === Esercizi.Esegui(); return; #endregion #region === Step 1 === Console.WriteLine("=== LINQ ==="); string firstName = "Roberto"; var lastName = 0.4; //lastName = "Ajolfi"; // ERRORE! //using var file = new StreamWriter(null); //var data = new List<int>{ 1, 2, 3, 4 }; List <Employee <int> > data = new List <Employee <int> > { new Employee <int>() }; Employee <int> firstEmployee = new Employee <int>(); Employee <string> secondEmployee; // Extension Methods string example = "230"; example.ToUpper(); Console.WriteLine(example.ToDouble()); var prefix = example.WithPrefix("[TST]"); Console.WriteLine(prefix); MyString example2 = new MyString(); example2.Value = "Example"; example2.Value.ToUpper(); // OPPURE example2.ToUpper(); foreach (var value in data) { Console.WriteLine("#" + value.Name); } Class1 class1 = new Class1(); //Class2 class2 = new ClassLib.Class2(); var person = new { firstName = "Roberto", lastName = "Ajolfi", eta = 12 }; var person2 = new { nome = "Alice", cognome = "Colella" }; var person3 = person2; firstEmployee.ID = 9; #endregion #region === Step 2 === // EVENTS var process = new BusinessProcess(); process.Started += Process_Started; process.Started += Process_Started1; process.Completed += CompletedProcess; process.StartedCore += Process_StartedCore; //process.ProcessData(); // DELEGATES Sum lamiaSomma = new Sum(PrimaSomma); //// OPPURE Sum lamiaSomma2 = PrimaSomma; // Sum == Func<int, int, int> // Func and Action Func <int, double, int> primaFunc = SecondaSomma; Func <int, int, int> secondaFunc = PrimaSomma; Action <int> primaAction; //// ERRORE!!! Wrong Signature ////lamiaSomma = SecondaSomma; //Chiamami(lamiaSomma); //Chiamami(PrimaSomma); //// ERRORE //Chiamami(SecondaSomma); #endregion #region === Step 3 === Func <int, int> lamdbaZero = x => 2 * x; Func <int, int> lamdbaZeroZero = x => { var result = 2 * x; return(result); }; Func <int, int> lamdbaZeroZeroZero = Multiply; lamdbaZeroZero(45); var list = new List <int> { 1, 2, 3, 4, 5, 6 }; //var results = Where(dataInt, x => x > 2); var results = list.Where(x => x > 2); Func <int, double, bool> lambdaOne = (x, y) => x > (int)y; #endregion #region === Step 4 === List <EmployeeInt> employees = new List <EmployeeInt> { new EmployeeInt { ID = 1, Name = "Roberto" }, new EmployeeInt { ID = 2, Name = "Alice" }, new EmployeeInt { ID = 3, Name = "Mauro" }, new EmployeeInt { ID = 4, Name = "Roberto" }, }; var result = employees.Where("ID", "1"); var result2 = employees.Where("Name", "Roberto"); // value => value * value ParameterExpression y = Expression.Parameter(typeof(int), "value"); var basettoni = new ParameterExpression[] { y }; Expression <Func <int, int> > squareExpression = Expression.Lambda <Func <int, int> >( Expression.Multiply(y, y), basettoni ); Expression <Func <int, int> > squareExpression2 = value => value * value; Func <int, int> funzione = squareExpression.Compile(); Console.WriteLine(funzione(3)); var emp = EmployeeInt.Empty; #endregion #region === Step 5 === var products = new List <Product> { new Product { ID = 1, ProductCode = "PC001" }, new Product { ID = 2, ProductCode = "PC001" }, new Product { ID = 1, ProductCode = "PC001" } }; int resultCount1 = products.Select(s => s).Distinct().Count(); int resultCount1a = products.Select(s => s).Distinct(new ProductComparer()).Count(); int resultCount2 = products.Select(s => new { s.ID, s.ProductCode }).Distinct().Count(); Console.WriteLine($"{resultCount1} - {resultCount1a} - {resultCount2}"); #endregion #region === Step 6 === List <Employee> objEmployee = new List <Employee>() { new Employee() { Name = "Ashish Sharma", Department = "Marketing", Country = "India" }, new Employee() { Name = "John Smith", Department = "IT", Country = "USA" }, new Employee() { Name = "Kim Jong", Department = "Sales", Country = "China" }, new Employee() { Name = "Marcia Adams", Department = "HR", Country = "USA" }, new Employee() { Name = "John Doe", Department = "Operations", Country = "Canada" } }; var emp1 = objEmployee.ToLookup(x => x.Country); Console.WriteLine("Grouping Employees by Country"); Console.WriteLine("---------------------------------"); foreach (var grouping in emp1) { Console.WriteLine(grouping.Key); // Lookup employees by Country foreach (var item in emp1[grouping.Key]) { Console.WriteLine("\t" + item.Name + "\t" + item.Department); } } #endregion }
static void Main(string[] args) { #region === Step 1 === Console.WriteLine("=== LINQ ==="); string firstName = "Roberto"; var lastName = 0.4; //lastName = "Ajolfi"; // ERRORE! //using var file = new StreamWriter(null); //var data = new List<int>{ 1, 2, 3, 4 }; List <Employee <int> > data = new List <Employee <int> > { new Employee <int>() }; Employee <int> firstEmployee = new Employee <int>(); Employee <string> secondEmployee; // Extension Methods string example = "230"; example.ToUpper(); Console.WriteLine(example.ToDouble()); var prefix = example.WithPrefix("[TST]"); Console.WriteLine(prefix); MyString example2 = new MyString(); example2.Value = "Example"; example2.Value.ToUpper(); // OPPURE example2.ToUpper(); foreach (var value in data) { Console.WriteLine("#" + value.Name); } Class1 class1 = new Class1(); //Class2 class2 = new ClassLib.Class2(); var person = new { firstName = "Roberto", lastName = "Ajolfi", eta = 12 }; var person2 = new { nome = "Alice", cognome = "Colella" }; var person3 = person2; firstEmployee.ID = 9; #endregion #region === Step 2 === // EVENTS var process = new BusinessProcess(); process.Started += Process_Started; process.Started += Process_Started1; process.Completed += CompletedProcess; process.StartedCore += Process_StartedCore; process.ProcessData(); // DELEGATES Sum lamiaSomma = new Sum(PrimaSomma); //// OPPURE Sum lamiaSomma2 = PrimaSomma; // Sum == Func<int, int, int> // Func and Action Func <int, double, int> primaFunc = SecondaSomma; Func <int, int, int> secondaFunc = PrimaSomma; Action <int> primaAction; //// ERRORE!!! Wrong Signature ////lamiaSomma = SecondaSomma; //Chiamami(lamiaSomma); //Chiamami(PrimaSomma); //// ERRORE //Chiamami(SecondaSomma); #endregion #region === Step 3 === Func <int, int> lamdbaZero = x => 2 * x; Func <int, int> lamdbaZeroZero = x => { var result = 2 * x; return(result); }; Func <int, int> lamdbaZeroZeroZero = Multiply; lamdbaZeroZero(45); var list = new List <int> { 1, 2, 3, 4, 5, 6 }; //var results = Where(dataInt, x => x > 2); var results = list.Where(x => x > 2); Func <int, double, bool> lambdaOne = (x, y) => x > (int)y; #endregion #region === Step 4 === List <EmployeeInt> employees = new List <EmployeeInt> { new EmployeeInt { ID = 1, Name = "Roberto" }, new EmployeeInt { ID = 2, Name = "Alice" }, new EmployeeInt { ID = 3, Name = "Mauro" }, new EmployeeInt { ID = 4, Name = "Roberto" }, }; var result = employees.Where("ID", "1"); var result2 = employees.Where("Name", "Roberto"); // value => value * value ParameterExpression y = Expression.Parameter(typeof(int), "value"); var basettoni = new ParameterExpression[] { y }; Expression <Func <int, int> > squareExpression = Expression.Lambda <Func <int, int> >( Expression.Multiply(y, y), basettoni ); Expression <Func <int, int> > squareExpression2 = value => value * value; Func <int, int> funzione = squareExpression.Compile(); Console.WriteLine(funzione(3)); #endregion }
private static void TestDelegate() { //DELEGATE Sum lamiasomma = PrimaSomma; //è uguale a scrivere: //Sum lamiasomma = new Sum(PrimaSomma); //lamiasomma = SecondaSomma; dà errore: SecondaSomma ha una firma diversa rispetto a quella definita in Sum Chiamami(lamiasomma); //o anche: Chiamami(PrimaSomma); var process = new BusinessProcess(); process.Started += Process_Started; //aggancio un EventHandler: una fz che sta in ascolto nel momento in cui viene sollevato un evento. //La funzione deve avere la stessa firma del Delegate che è il tipo di Started. process.Completed += Process_Completed; process.StartedCore += Process_StartedCore; process.CompletedCore += Process_CompletedCore; process.ProcessData(); //Possibili Delegate sono le Func e le Action: Func <int> primaFunc; //Func si usa per funzioni con un parametro di output e n di input //è come definire sopra: public delegate int primaFunc(); //Qui sto dicendo che restituisce un int e non prende argomenti //Come tipi: Sum=Func<int, int, int>, in cui i primi tipi indicano gli input e l'ultimo indica il tipo dell'output Action <int> primaAction; //Le Action si usano per funzioni che non hanno valori in uscita /* Func e Action sono dei Delegate, e gli posso assegnare delle funzioni con i parametri input/output descritti * La comodità è non definire un Delegate, ma si usa un Delegate già esistente, che viene rappresentato in questo modo più semplice*/ //Anche le LAMBDA-EXPRESSION sono dei modi per scrivere metodi e passarli ad altri metodi Func <int, int> lambdaZero = x => 2 * x; //x=>2*x è una Lambda-Expression, che infatti è una funzione, e possiamo assegnare a Func<int,int> //Questa Lambda-Expression e la funzione Mult definita sotto sono la stessa cosa. Farlo così però è più semplice Func <int, int> lambdaMult = x => { return(2 * x); }; //tra graffe si aspetta un return (perchè in teoria possono esserci più righe quindi se lo aspetta Func <int, int> lambdaZeroZero = Mult; List <int> myList = new List <int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; var result = Where(myList, x => x > 2); //la funzione che prendo in input, sottoforma di Lambda-Expression è quella che sarà la condizione da controllare dentro la funzione Where foreach (var item in result) { Console.WriteLine(item); } Func <int, int, int> lambdaOne = (x, y) => x * y; //due input, un output Func <int, double, bool> lambdaTwo = (x, y) => x > (int)y; }
static void Main(string[] args) { #region VARIABILI DI TIPO IMPLICITO e EXTENSION METHODS Console.WriteLine("LINQ"); string firstName = "Giulia"; var lastName = "Soresini"; // IL COMPILATORE CAPISCE CHE è STRINGA //using var file = new StreamWriter(null); List <int> data = new List <int> { 1, 2, 3, 4 }; foreach (var value in data) { Console.WriteLine("#" + value); } //poi se mi creo una classe employee e faccio la lista, posso usare lo stesso foreach, cambia il tipo di value che prima eraint ora employee List <Employee <int> > data1 = new List <Employee <int> > { }; foreach (var value in data1) { Console.WriteLine("#" + value.Name); // tipo viene capito non a runtime, ma quando lo dichiaro direttamente } Employee <int> firstEmployee = new Employee <int>(); Employee <string> secondEmployee; Class1 class1 = new Class1(); //Class2 class2 = new ClassLib.Class2(); non referenziabile perchè in diverso assembl e internal var person = new { firstName = "Roberto", lastName = "Ajolfi", eta = 12 }; var person2 = new { nome = "Alice", cognome = "Colella" }; var person3 = person2; firstEmployee.ID = 9; // extension methods string example = "230"; example.ToUpper(); Console.WriteLine(example.ToDouble()); // METODO CHE HO AGGIUNTO var prefix = example.WithPrefix("[TST]"); Console.WriteLine(prefix); #endregion e FUNC AND ACTION #region EVENTI E DELEGATI (business process) e FUNC e ACTION //uso delegato //Sum lamiasomma = new Sum(PrimaSomma); // lamiasomma mia somma è del tipo Sum, perchè il metodo ha la stessa firma del delegate // oppure //Sum lamiasomma = PrimaSomma; // Sum è come scrivere Func<int,int> //// POSSO PASSARE LA FUNZIONE A UN ETOFDO CHIAMAMI //Chiamami(lamiasomma); // esempio business process var process = new BusinessProcess(); // istanza notifier process.Started += Process_Started; // aggiungo alla lista dei delegate ( mi sottoscrivo) process.Started += Process_Started1; process.Completed += Process_Completed; //NON STO CHIAMANDO IL METODO, QUINDI NON MI SERVONO LE PARENTESI TONDE process.ProcessData(); process.StartedCore += Process_StartedCore; //func e action // sono delegate che già esistono, sono più facili da rappresentare perchè fatti coi generics Func <int> primaFunc; // è uguale a fare public delegate int primaFunc(); //posso passargli un metodo dopo l'uguale,tipo Func <int, int, int> PrimaFunc = PrimaSomma; //l'ultimo int è il ritorno, gli altri due sono i parametri // così sto usando il metodo PrimaSomma, che ha questa firma Func <int, double, int> SecondaFunc = SecondaSomma; // func sostituisce il delegate, va bene per quelle funzioni che hanno tipo di ingresso (n) e uscita Action <int> primaAction; // è una funzione che non ha valori in uscita (void) // posso sempre usare i tipi predefiniti eventhandler o func e action al posto del delegate // definsico il mio delegate solo se mi serve un nome specifico //// ERRORE!!! Wrong Signature ////lamiaSomma = SecondaSomma; //Chiamami(lamiaSomma); //Chiamami(PrimaSomma); //// ERRORE //Chiamami(SecondaSomma); #endregion #region LAMBDA EXPRESSIONS // lambda expressions è un delegate qindi il tipo di ritorno deve essere un delegate Func <int, int> lambdaZero = x => 2 * x; // su una riga sottintende return, altrimenti lo devo mettere con le graffe Func <int, int> lamdbaZeroZero = x => { var result = 2 * x; return(result); }; // è uguale a scrivere Func <int, int> lambdaZeroZerozERO = Mult; lamdbaZeroZero(45); //list.where nella slides var dataInt = new List <int> { 1, 2, 3, 4, 5, 6 }; //var results = Where(dataInt, x => x > 2); // where rprende qualsiasi classe implementi IEnmerable var results = dataInt.Where(x => x > 2); Func <int, double, bool> lambdaOne = (x, y) => x > (int)y; #endregion #region EXPRESSION TREES // expression tree //supponiamo di avere una lista doi employees List <EmployeeInt> employees = new List <EmployeeInt> { new EmployeeInt { ID = 1, Name = "Roberto" }, new EmployeeInt { ID = 2, Name = "Alice" }, new EmployeeInt { ID = 3, Name = "Mauro" }, new EmployeeInt { ID = 4, Name = "Roberto" }, }; //se volessi fare un where dinamico, in cui prendo da input due stringhe // una volta su ID, una volta su Nome ecc.. --> o nel codice mi costruisco tutte le espressioni possibili // o rendo dinamica la creazione della lambda che passo a where var result = employees.Where("ID", "1"); // mettere where in StringExtensions var result2 = employees.Where("Name", "Roberto"); // expression ParameterExpression y = Expression.Parameter(typeof(int), "x"); // "" ho solo il nome del parametro così come viene stampato y si chiama x //QUI HO DICHIARATO UN PARAMETRO, CHE POI DEVO USARE, che si chiama y (che è un oggetto che ha due proprietà, cjhe sono il tipo e il nome in cui lo vedo stampato Expression <Func <int, int> > squareExpression = Expression.Lambda <Func <int, int> >( // lambda vuole un generic che le dica come essere fatta, lielo dico con un deelegate // voglio una lambda che prenda int e dia int Expression.Multiply(y, y), // corpo della lambda, poi parametri (è la firma di lambda, che è un metodo di Expression) new ParameterExpression[] { y }); //array di parametry a cui passo il mio y //dopo di che faccio il compile e a quel punto posso richiamare func Expression <Func <int, int> > squareExpression2 = value => value * value; Func <int, int> funzione = squareExpression.Compile(); Console.WriteLine(funzione(3)); #endregion }