280 likes | 393 Vues
Explore LINQ query syntax, Visitor Pattern implementation with POJO, and delegates manipulation in Java. Learn about inline and lambda implementations for enhanced code functionality. Understand extension methods for class enhancement.
E N D
From (Visitor) to LINQ LINQ (this is where we ends in this presentation): var query = from a in accounts.TestData where a.Balance > 1e6 select a; foreach(Account a in query) Console.WriteLine(a.Balance);
Operations on a container without Visitor //Doubling evens for(int i = 0; i < con1.N; i++) { if(con1.Get(i) % 2 == 0) con1.Update(i, con1.Get(i) * 2); } //Doubling all for(int i = 0; i < con1.N; i++){ con1.Update(i, con1.Get(i) * 2); } //Increasing small ones by one for(int i = 0; i < con1.N; i++){ if(con1.Get(i) < 10) con1.Update(i, con1.Get(i) + 1); }
Visitor in POJO(Plain Old Java Objects) interface Visitor { public int visit(MyInteger number);}interface Visitable { public int accept(Visitor visitor);}class MyInteger implements Visitable { private int value; MyInteger(int i) { this.value = i; } public int accept(Visitor visitor) { return visitor.visit(this); } public int getValue() { return value; }} Can implement selection criteria here
class SubtractVisitor implements Visitor { int value; public SubtractVisitor(int value) { this.value = value; } public int visit(MyInteger i) { System.out.println("Subtract integer"); return (i.getValue() - value); } }
Visitor implemented with delegates ModifyElement and CheckElement are delegates public class Accounts { private List<Account> TestData { get; set; } public Accounts(){ TestData = new List<Account>(); TestData.Add(new Account { Balance = 2222 }); TestData.Add(new Account { Balance = 22222 }) …. More test data} public void ModifyAll(ModifyElement f) {//Applies f to all elements in the container foreach (Account a in TestData) f(a); } public void ModifySome(ModifyElement f, CheckElement p) { //Applies f only to elements in the containerthat satisfy p foreach (Account a in TestData) if (p(a)) f(a);} }
The delegates public delegate boolCheckElement(Account e); public delegate Account ModifyElement(Account e);
Simple implementation • Just a class with operations with an appropriate signature public class AccountOperations { public Account PrintBalance(Account a) { Console.WriteLine(a.Balance); return null; } public Account DoubleBalance(Account a) { a.Balance *= 2; return a; } public Account ClearBalance(Account a) { a.Balance = 0f; return a; } public bool IsBigAccount(Account a) { return a.Balance > 1e6 && a.Balance <= 1e7; } ….. }
Driver Accounts accounts = new Accounts(); AccountOperations oper = new AccountOperations(); Console.WriteLine("TestData: "); ModifyElement print = oper.PrintBalance; accounts.ModifyAll(print); Console.WriteLine("Write big accounts"); CheckElement bigAccount = oper.IsBigAccount; accounts.ModifySome(print, bigAccount); Console.WriteLine("Clear small accounts"); CheckElement small = oper.IsSmallAccount; ModifyElement clear = oper.ClearBalance; accounts.ModifySome(clear, small); accounts.ModifyAll(print);
Use anonymous delegates • Given following delegate and method: • delegate int MyDelegate(int n); • void MyMethod(MyDelegate f){...} • Example on syntax for implementing delegate method: • MyDelegate doubleUp=delegate(int n){return 2*n;}; • MyMethod(doubleUp); • or shorter: • MyMethod(delegate(int n){return 2*n;}); • This is called inline implementation
Exercise • Rewrite delegate methods (Even, Double, LessThan10, etc.) in visitor example to use anonymous delegates. • Consider where it is (not) a good idea to use inline implementation
Driver with Anonymous delegate Console.WriteLine("TestData: "); ModifyElement print = delegate(Account a) { Console.WriteLine(a.Balance); return null; }; accounts.ModifyAll(print); Console.WriteLine("Write big accounts"); accounts.ModifySome(print, delegate(Account a) { return a.Balance > 1e6 && a.Balance <= 1e7; } ); The Print delegate is not inline as it is used multiple times
Lamda expression • Another way of defining anonymous methods // finds x’s bigger than 5 Predicate myPredicate = x=>x>5 myList.FindAll(myPredicate); //or myList.FindAll (x=>x>5); How to pronounce ”=>”: • Anders Hejlsberg: I usually read the => operator as "becomes" or "for which". For example,Func f = x => x * 2;Func test = c => c.City == "London";reads as "x becomes x * 2" and "c for which c.City equals London"
Lamda expression ModifyElement print = a=> { Console.WriteLine(a.Balance); return null; }; accounts.ModifyAll(print); Console.WriteLine("Write big accounts"); accounts.ModifySome(print, a=>a.Balance > 1e6 && a.Balance <= 1e7; );
Extention methods • It is possible to extend methods to a class without using inheriance • In fact, you might even extend a sealed class • This is done by using extention methods. • An extension method is a static method in a static class • By adding ‘this classname’ to the parameterlist, it becomes an extention method to classname
Example static class ExtensionEx { public static void WriteToConsole(this string s) { Console.WriteLine(s); } } Use: String s = "Hello"; s.WriteToConsole(); Is this really OO? Yes, it is just another way to write ExtentionEx.WriteToConsole(s);
Extension methods are the base of linq • Sample implementation of Where public static IEnumerable < TSource > Where < TSource > ( this IEnumerable < TSource > source, Func < TSource, bool > predicate) { foreach(TSource item in source) if (predicate(item)) yield return item; } yield: Start to return elements in a collection before all elements are known
Formula 1, ex1 • Using the delegates, anonymious methods and predicates IEnumerable < Racer > brazilChampions = Formula1.GetChampions(). Where(r = > r.Country == “Brazil”). OrderByDescending(r = > r.Wins). Select(r = > r); foreach (Racer r in brazilChampions) { Console.WriteLine(“{0:A}”, r); }
Exercise • Implement ‘Where’ and ‘Select’ in visitor example. • ”Where” has the same role as ”CheckElement” • ”Select” has the same role as ”ModifyElement”
Extention Methods (Where and Select) staticclassExtentions { publicstaticIEnumerable<int> Where(thisContainer source, Func<int, bool> predicate) { for (int i = 0; i < source.N; i++) { int item =source.Get(i); if (predicate(item)) yieldreturn item; } } publicstaticIEnumerable<int> Select(thisIEnumerable<int> source, Func<int, int> predicate) { foreach(int item in source) yieldreturn predicate(item); } }
Double all evens foreach (intiincon1 .Where(x => x % 2 == 0) .Select(r => r * 2) { Console.WriteLine(i); }
Anonymous types • Partly from MSDN: • Anonymous types provide a convenient way to encapsulate a set of read-only properties into a single object without having to explicitly define a type first. • The type name is generated by the compiler and is not available at the source code level. The type of each property is inferred by the compiler. • You create anonymous types by using the new operator together with an object initializer • The vartype is telling that it is an anonymous type var v = new { Amount = 108, Message = "Hello" }; Console.WriteLine(v.Amount+ v.Message);
Anonymous types • Partly from MSDN: • Anonymous types contain one or more public read-only properties. • That means that if you change a property value, you will get a new type. • No other kinds of class members, such as methods or events, are valid. • The expression that is used to initialize a property cannot be null, an anonymous function, or a pointer type. • The most common scenario is to initialize an anonymous type with properties from another type. • If you do not specify member names in the anonymous type, the compiler gives the anonymous type members the same name as the property being used to initialize them. • You must provide a name for a property that is being initialized with an expression, as shown in the previous slide.
Anonymous types • Partly from MSDN: • The most common scenario is to initialize an anonymous type with properties from another type. • In the following example, assume that a class exists that is named Product. • Class Product includes Color and Price properties, together with other properties that you are not interested in. • Variable products is a collection of Product objects. • The anonymous type declaration starts with the new keyword. The declaration initializes a new type that uses only two properties from Product. • This causes a smaller amount of data to be returned in the query. • The names of the properties of the anonymous type are Color and Price.
Example (using LINQ) • From MSDN: var productQuery = fromprod in products selectnew { prod.Color, prod.Price }; foreach(var v in productQuery) { Console.WriteLine("Color={0}, Price={1}", v.Color, v.Price); }
Formula 1, ex2 • LINQ: var query = from r in Formula1.GetChampions() where r.Country == “Brazil” orderby r.Wins descending select r; foreach (Racer r in query) { Console.WriteLine(“{0:A}”, r); } Compare this to Formula 1, ex1
Another example of simple LinqMore in next presentation var query = from a in accounts.TestData where a.Balance > 1e6 select a; foreach(Account a in query) Console.WriteLine(a.Balance);