from (visitor) to linq
DESCRIPTION
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 - PowerPoint PPT PresentationTRANSCRIPT
From (Visitor) to LINQLINQ (this is where we ends in this presentation):
1
var query = from a in accounts.TestData where a.Balance > 1e6 select a;
foreach (Account a in query) Console.WriteLine(a.Balance);
2
Operations on a container without Visitor
//Doubling evensfor (int i = 0; i < con1.N; i++) { if (con1.Get(i) % 2 == 0)
con1.Update(i, con1.Get(i) * 2);}//Doubling allfor (int i = 0; i < con1.N; i++){ con1.Update(i, con1.Get(i) * 2);}//Increasing small ones by onefor (int i = 0; i < con1.N; i++){ if (con1.Get(i) < 10) con1.Update(i, con1.Get(i) + 1);}
4
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
5
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
6
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);}}
ModifyElement and CheckElement are delegates
The delegates
7
public delegate bool CheckElement(Account e); public delegate Account ModifyElement(Account e);
Simple implementation
• Just a class with operations with an appropriate signature
8
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
9
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
10
11
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
12
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
13
// finds x’s bigger than 5Predicate myPredicate = x=>x>5myList.FindAll(myPredicate);//ormyList.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
14
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
15
Example
16
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
17
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
18
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);}
19
Exercise
• Implement ‘Where’ and ‘Select’ in visitor example.• ”Where” has the same role as ” CheckElement” • ”Select” has the same role as ” ModifyElement”
20
Extention Methods (Where and Select)
static class Extentions { public static IEnumerable<int> Where(this Container source,
Func<int, bool> predicate) { for (int i = 0; i < source.N; i++) { int item =source.Get(i); if (predicate(item)) yield return item; } }
public static IEnumerable<int> Select(this IEnumerable<int> source, Func<int, int>
predicate) { foreach(int item in source) yield return predicate(item); }}
21
Double all evens
foreach (int i in con1.Where(x => x % 2 == 0).Select(r => r * 2)
{ Console.WriteLine(i);
}
22
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 var type is telling that it is an anonymous type
var v = new { Amount = 108, Message = "Hello" }; Console.WriteLine(v.Amount + v.Message);
23
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.
24
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.
25
Example (using LINQ)
• From MSDN:
var productQuery = from prod in products select new { prod.Color, prod.Price };
foreach (var v in productQuery) { Console.WriteLine("Color={0}, Price={1}", v.Color, v.Price);
}
Formula 1, ex2
• LINQ:
26
var query = from r in Formula1.GetChampions()where r.Country == “Brazil”orderby r.Wins descendingselect 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
27
var query = from a in accounts.TestData where a.Balance > 1e6 select a;
foreach (Account a in query) Console.WriteLine(a.Balance);