Advanced NET Programming I 5 th Lecture http
- Slides: 5
Advanced. NET Programming I 5 th Lecture http: //d 3 s. mff. cuni. cz/~jezek Pavel Ježek pavel. jezek@d 3 s. mff. cuni. cz CHARLES UNIVERSITY IN PRAGUE faculty of mathematics and physics Some of the slides are based on University of Linz. NET presentations. © University of Linz, Institute for System Software, 2004 published under the Microsoft Curriculum License (http: //www. msdnaa. net/curriculum/license_curriculum. aspx)
Lambda Expressions (2) Expression or statement body Implicitly or explicitly typed parameters Examples: x => x + 1 // Implicitly typed, expression body x => { return x + 1; } // Implicitly typed, statement body (int x) => x + 1 // Explicitly typed, expression body (int x) => { return x + 1; } // Explicitly typed, statement body (x, y) => x * y // Multiple parameters () => Console. Write. Line() // No parameters A lambda expression is a value, that does not have a type but can be implicitly converted to a compatible delegate type delegate R Func<A, R>(A arg); Func<int, int> f 1 = x => x + 1; Func<int, double> f 2 = x => x + 1; Func<double, int> f 3 = x => x + 1; Pavel Ježek C# 3. 0 and. NET 3. 5 // Ok // Error – double cannot be // implicitly converted to int
Outer Variables If anonymous methods access variables of the enclosing method these variables are evacuated into a dummy object (capturing) – all anonymous methods and the enclosing method itself are then using a single “evacuated” variable (see next slide). delegate int Adder(); class Test { static Adder Create. Adder() { int x = 0; return delegate { x++; return x; }; } static void Main() { Adder add = Create. Adder(); Console. Write. Line(add()); } dummy object delegate (closure) 2 3 10 add x++; return x; The dummy object lives as long as the delegate object } Output: 1 2 3 Anonymous methods in C# always exist only as closures, never as “lambda functions” with free variables (open bindings)!
Example Output: delegate void My. Delegate(); class Program { static My. Delegate Foo() { int x = 1; Console. Write. Line("Foo: x = {0}", x); My. Delegate d = delegate { x++; Console. Write. Line("delegate: x = {0}", x); }; d(); Console. Write. Line("Foo: x = {0}", x); My. Delegate d 2 = delegate { x += 10; Console. Write. Line("second delegate: x = {0}", x); }; d 2(); d(); Console. Write. Line("Foo: x = {0}", x); return d 2; } static void Main(string[] args) { My. Delegate m; Console. Write. Line(“--- Main: (m = Foo())(); "); (m = Foo())(); m(); Console. Write. Line(“--- Main: Foo()(); "); Foo()(); m(); } } --- Main: (m = Foo())(); Foo: x = 1 delegate: x = 2 delegate: x = 3 Foo: x = 3 second delegate: x = 13 delegate: x = 14 Foo: x = 14 second delegate: x = 24 second delegate: x = 34 --- Main: Foo()(); Foo: x = 1 delegate: x = 2 delegate: x = 3 Foo: x = 3 second delegate: x = 13 delegate: x = 14 Foo: x = 14 second delegate: x = 24 second delegate: x = 44
Lambda Expressions (2 b) Expression or statement body Implicitly or explicitly typed parameters Examples: x => x + 1 // Implicitly typed, expression body x => { return x + 1; } // Implicitly typed, statement body (int x) => x + 1 // Explicitly typed, expression body (int x) => { return x + 1; } // Explicitly typed, statement body (x, y) => x * y // Multiple parameters Lambda expressions in C# always exist only as closures, () => Console. Write. Line() // No parameters and never as “lambda functions” with free variables (open bindings)! A lambda expression is a value, that does not have a type but can be implicitly converted to a compatible delegate type delegate R Func<A, R>(A arg); Func<int, int> f 1 = x => x + 1; Func<int, double> f 2 = x => x + 1; Func<double, int> f 3 = x => x + 1; Pavel Ježek C# 3. 0 and. NET 3. 5 // Ok // Error – double cannot be // implicitly converted to int