Monday 10 September 2012

Lambda Expressions

A Lambda expression is an Anonymous function, that is more concise and flexible. You can use lambda expression to create inline delegates or expression tree type(s).

By using lambda expressions, you can write local functions that can be passed as arguments or returned as the value of function calls. Lambda expressions are particularly helpful for writing LINQ query expressions.

Although both anonymous methods and lambda expressions allow you define the method implementation inline, but they do slightly differ on how they are implemented. An anonymous method explicitly requires you to define the parameter types and the return type for a method, where as lambda expression uses the type inference feature which allows the compiler to infer the type of the variable based on the context.

A typical lambda expression looks like:

           Input Parameter => Expression or Statement block

The symbol => is known as lambda operator. On the left hand side of lambda operator you specify input parameters (if any) and you put the expression or statement block on the other side.

A simplest example of lambda expression:

           x => x * x
        
The lambda expression above, specifies a parameter that’s named x and returns the value of x squared.

Operator Lambda:

The symbol => is known as lambda operator, which is read as “goes to”.  The => operator has the same precedence as assignment (=) and is right-associative.

The term right-associative means when two or more operators that have the same precedence are present in an expression, they are evaluated in order from right to left.

Expression Lambda:

A lambda expression with an expression on the right side is called an expression lambda.An expression lambda returns the result of the expression and takes the following basic form:

           (Input Parameters) => Expression

The parentheses are optional if the lambda has one input parameter:

           x => x + 1

Two or more input parameters are separated by commas and enclosed in parentheses:

           (x, y) => x == y

Sometimes it is difficult for the compiler to infer the input types. In that case, you can specify the types explicitly:

           (int x, string s) => s.Length > x

Specify zero input parameters with empty parentheses:

           () => SomeMethod();

           () => new Orders(7));

Statement Lambda:

A statement lambda resembles an expression lambda except that the statement(s) is enclosed in braces followed by a semicolon(;):

           (Input Parameters) => {Statement;};

The body of a statement lambda can consist of any number of statements:

           (int x) => { if (x==1)  return x;  else return  x * x;  };

Lambdas with Inline Delegates:

Earlier we used to create inline delegates with the help of Anonymous methods only, like:


Nowdays we can create inline delegates using Lambda expressions, that is the most convenient way to create inline delegates.


In the example, notice that the delegate signature has one implicitly-typed input parameter of type int, and returns an int. The lambda expression can be converted to a delegate of that type because it also has one input parameter (x) and a return value that the compiler can implicitly convert to type int. When the delegate is invoked by using an input parameter of 5, it returns a result of 25.

Lambdas with Generic Delegates:

Func<>, Action<> and Expression<> are the new generic delgates introduced by Microsoft. Many Standard query operators have an input parameter whose type is one of the Func<T, TResult> family of generic delegates.

The Func<> delegates are very useful for encapsulating user-defined expressions that are applied to each element in a set of source data.


In the example, the Func<int, bool> delegate, when it is invoked, will return true or false to indicate whether the input parameter is odd or even number. Like:

           Func<int, bool> myFunc = n => n % 2 == 1;
           bool result = myFunc(4); // returns false
The Func delegate is instantiated as Func<int,bool> myFunc where int is an input parameter and bool is the return value. The return value is always specified in the last type parameter.

Type Inference in Lambdas:

When writing lambdas, you often do not have to specify a type for the input parameters because the compiler can infer the type based on the lambda body, the underlying delegate type, and other factors as described in the C# Language Specification.

For most of the standard query operators, the first input is the type of the elements in the source sequence. So if you are querying an IEnumerable<Customer>, then the input variable is inferred to be a Customer object, which means you have access to its methods and properties:

           customers.Where(c => c.City == "London");

The general rules for lambdas are as follows:
  • The lambda must contain the same number of parameters as the delegate type.
  • Each input parameter in the lambda must be implicitly convertible to its corresponding delegate parameter.
  • The return value of the lambda (if any) must be implicitly convertible to the delegate's return type.

Variable Scope in Lambdas:

Lambdas can refer to outer variables that is in the scope of the method or type in which the lambda is defined.

The following rules apply to variable scope in lambda expressions:
  • A variable that is captured will not be garbage-collected until the delegate that references it goes out of scope.
  • Variables introduced within a lambda expression are not visible in the outer method.
  • A lambda expression cannot directly capture a ref or out parameter from an enclosing method.
  • A return statement in a lambda expression does not cause the enclosing method to return.
  • A lambda expression cannot contain a goto statement, break statement, or continue statement whose target is outside the body or in the body of a contained anonymous function.
  • An outer variable must be definitely assigned before it can be consumed in a lambda expression. The following example demonstrates these rules.

How to use Lembdas in LINQ:

Lambda expressions are not directly used in queries syntax. They are used in query based method like Where or FindAll. But query expressions can contain lembda enabled method calls.

Example 1: The following example demonstrates how to use a lambda expression in a method-based query by using the Enumerable.Where standard query operator. Note that the Where method in this example has an input parameter of the delegate type Func<TResult> and that delegate takes an integer as input and returns a Boolean. The lambda expression can be converted to that delegate.


Example 2: The following example demonstrates how to use a lambda expression in a method call of a query expression. The lambda is necessary because the Sum() standard query operator cannot be invoked by using query syntax.



How to use Lembdas outside LINQ:

Lambda expressions are not limited to LINQ queries. You can use them anywhere a delegate value is expected, that is, wherever an anonymous method can be used.

Example: The following example shows how to use a lambda expression in a Windows Forms event handler. Notice that the types of the inputs (Object and MouseEventArgs) are inferred by the compiler and do not have to be explicitly given in the lambda input parameters.



Framework:

.Net 3.0, 3.5, 4.0, 4.5

References:

Monday 3 September 2012

Extension Methods

In typical Object Oriented developement, extending an existing type is achieved through creating derived types. But consider a scenario where the base type is not inheritable or sealed, in that case there is no way to extend these types. An example of such type is the System.String class.

With the launch of  Microsoft .Net Framework 3.0, it was made possible. A new feature named Extension Methods was introduced to lets you extend any existing type's functionality, even when a type is not inheritable. And these extension methods play a crucial role in the implementation of LINQ.
  • Extension methods allow you to add new method(s) to an existing type without creating a new derived type or recompiling the old type.
  • Extension methods can be written for Value, Reference and Interface types.
  • Extension methods are a special kind of static method, but they are called as instance method.
  • Extension methods create the illusion that they are defined on a real type, but in reality, no changes are made to the original types.
  • Extension methods cannot access private variables of the type they are extending.
  • The most common Extension methods are the LINQ standard query operators that add query functionality to the existing System.Collections.IEnumerable and System.Collections.Generic.IEnumerable<T> types.
It is not a standard object-oriented concept; it is a specific Microsoft® .NET Framework implementation feature that opens up a new set of possibilities. It's worth noting that the intermediate language (IL) generated by the compiler translates your code into a static method call. Therefore, the principle of encapsulation is not really being violated.

 

Creating Extension Methods:

In general, you will probably be calling extension methods far more often than implementing your own.

1. Create a Class Library with the name StringExtensions.


2. Add reference to System.Core.dll. This reference is required because the compiler needs System.Runtime.CompilerServices.ExtensionAttribute for creating the extension methods. In C#, you do not need to write this attribute; you should use the this modifier for the first parameter to create an extension method. The compiler automatically emits ExtensionAttribute for extension methods.

3. Define a static class with the name StringExtension to contain the extension methods. The class must be static and visible to client code. For more information about accessibility rules, see Access Modifiers.

4. Implement the extension method as a static method with at least the same visibility as the containing class. The first parameter of the method specifies the type that the method operates on; it must be preceded with the this modifier.


5. Build the project.

 

Calling Extension Methods:

1. Create a Console Application with the name StringExtensionTest.


2. Add reference to previously created assembly named StringExtensions.

3. Add a using directive to specify the namespace that contains the extension methods. Extension methods come into scope at namespace level. It means all the extension methods of all the classes defined in a namespace will brought into scope with this using directive.

4. Create the object of class and you will start seeing the extension methods in IntelliSense for this object.

5. Note that the first parameter is not specified by calling code because it represents the type on which the operator is being applied, and the compiler already knows the type of your object. You only have to provide arguments for parameters 2 through n.



6. Run the application.

 

Compilation & Binding of Extension Methods:

1. Extension methods are used to extend a class or interface, but not to override them.

2. An extension method with the same name and signature as an interface or class's instance method will never be called.

3. At compile time, extension methods always have lower priority than instance methods defined in the type itself. In other words, if a type has a method named Process(int i), and you have an extension method with the same signature, the compiler will always bind to the instance method.

4. When the compiler encounters a method invocation, it first looks for a match in the type's instance methods. If no match is found, it will search for any extension methods that are defined for the type, and bind to the first extension method that it finds.

5. At the time of actual compilation, the extension method call gets converted to static method call. So the intermediate language (IL) generated after compilation, has a static method call corresponding to an extension method.

 

Security:

Extension methods present no specific security vulnerabilities, because they cannot access any private data in the extended class.

 

Guidlines:

In general, Microsoft recommend that you implement extension methods sparingly and only when you have to. Whenever possible, client code that must extend an existing type should do so by creating a new type derived from the existing type. For more information, see Inheritance.

When using an extension method to extend a type whose source code you cannot change, you run the risk that a change in the implementation of the type will cause your extension method to break.

If you do implement extension methods for a given type, remember the following two points:
  • An extension method will never be called if it has the same signature as a method defined in the type.
  • Extension methods are brought into scope at the namespace level. For example, if you have multiple static classes that contain extension methods in a single namespace named Extensions, they will all be brought into scope by the using Extensions; directive.

 

Framework:

.Net 3.0, 3.5, 4.0, 4.5