Tuesday, September 29, 2009

New features C# 3.0:Lambda Expressions

Lambda expression is an anonymous function that can contain expressions and statements, and can be used to create delegates or expression tree types.
All lambda expressions use the lambda operator =>, which is read as "goes to". The left side of the lambda operator specifies the input parameters (if any) and the right side holds the expression or statement block. The lambda expression x => x * x is read "x goes to x times x." This expression can be assigned to a delegate type as follows:
delegate int del(int i);
static void Main(string[] args){ del myDelegate = x => x * x; int j = myDelegate(5); //j = 25}
To create an expression tree type:
using System.Linq.Expressions;
namespace ConsoleApplication1
{class Program{
static void Main(string[] args){
Expression< del > myET = x => x * x;} }}
The => operator has the same precedence as assignment (=) and is right-associative.
Lambdas are used in method-based LINQ queries as arguments to standard query operator methods such as Where.
When you use method-based syntax to call the Where method in the Enumerable class (as you do in LINQ to Objects and LINQ to XML) the parameter is a delegate type System..::.Func<(Of <(T, TResult>)>). A lambda expression is the most convenient way to create that delegate. When you call the same method in, for example, the System.Linq..::.Queryable class (as you do in LINQ to SQL) then the parameter type is an System.Linq.Expressions..::.Expression where Func is any Func delegates with up to five input parameters. Again, a lambda expression is just a very concise way to construct that expression tree. The lambdas allow the Where calls to look similar although in fact the type of object created from the lambda is different.
A lambda expression with an expression on the right side is called an expression lambda. Expression lambdas are used extensively in the construction of Expression Trees. An expression lambda returns the result of the expression and takes the following basic form: (input parameters) => expression
The parentheses are optional only if the lambda has one input parameter; otherwise they are required. Two or more input parameters are separated by commas enclosed in parentheses:  (x, y) => x == y
A statement lambda resembles an expression lambda except that the statement(s) is enclosed in braces: (input parameters) => {statement;}
delegate void TestDelegate(string s);
TestDelegate myDel = n => { string s = n + " " + "World"; Console.WriteLine(s); }; myDel("Hello");
Lambdas with the Standard Query Operators have an input parameter whose type is one of the Func<(Of <(T, TResult>)>) family of generic delegates. The Func<(Of <(T, TResult>)>) delegates use type parameters to define the number and type of input parameters, and the return type of the delegate. Func delegates are very useful for encapsulating user-defined expressions that are applied to each element in a set of source data. For example, consider the following delegate type:
public delegate TResult Func(TArg0 arg0)
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. 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, 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 Lambda Expressions Lambdas can refer to outer variables that are in scope in the enclosing method or type in which the lambda is defined. Variables that are captured in this manner are stored for use in the lambda expression even if variables would otherwise go out of scope and be garbage collected. An outer variable must be definitely assigned before it can be consumed in a lambda expression.
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.

New features C# 3.0:Extension Methods

Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type.
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<(Of <(T>)>) types. To use the standard query operators, first bring them into scope with a using System.Linq directive. Then any type that implements IEnumerable<(Of <(T>)>) appears to have instance methods such as GroupBy, OrderBy, Average, and so on. You can see these additional methods in IntelliSense statement completion when you type "dot" after an instance of an IEnumerable<(Of <(T>)>) type such as List<(Of <(T>)>) or Array.
The following example shows how to call the standard query operator OrderBy method on an array of integers. The expression in parentheses is a lambda expression.
class ExtensionMethods2 {
static void Main(){
int[] ints = { 10, 45, 15, 39, 21, 26 };
var result = ints.OrderBy(g => g);
foreach (var i in result)
{System.Console.Write(i + " "); }
} }
//Output: 10 15 21 26 39 45
Extension methods are defined as static methods but are called by using instance method syntax. Their first parameter specifies which type the method operates on, and the parameter is preceded by the this modifier. Extension methods are only in scope when you explicitly import the namespace into your source code with a using directive.
The following example shows an extension method defined for the System..::.String class. Note that it is defined inside a non-nested, non-generic static class:
namespace ExtensionMethods{
public static class MyExtensions{
public static int WordCount(this String str)
{ return str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length; }
}
The WordCount extension method can be brought into scope with this using directive:
using ExtensionMethods; And it can be called from an application by using this syntax:
string s = "Hello Extension Methods";
int i = s.WordCount();

New features C# 3.0:Object and Collection Initializers

Object initializers let you assign values to any accessible fields or properties of an object at creation time without having to explicitly invoke a constructor. The following example shows how to use an object initializer with a named type.
private class Cat{ // Auto-implemented properties
public int Age { get; set; }
public string Name { get; set; } }
static void MethodA() { // Object initializer
Cat cat = new Cat { Age = 10, Name = "Sylvester" }; }
Object Initializers with anonymous types Although object initializers can be used in any context, they are especially useful in LINQ query expressions. Query expressions make frequent use of anonymous types, which can only be initialized with an object initializer. In the select clause, a query expression can transform objects of the original sequence into objects whose value and shape may differ from the original. This is very useful if you want to store only a part of the information in each object in a sequence. In the following example, assume that a product object (p) contains many fields and methods, and that you are only interested in creating a sequence of objects that contain the product name and the unit price.
var productInfos = from p in products  select new { p.ProductName, p.UnitPrice };
When this query is executed, the productInfos variable will contain a sequence of objects that can be accessed in a foreach statement as shown in this example:  foreach(var p in productInfos){...}
Each object in the new anonymous type has two public properties which receive the same names as the properties or fields in the original object. You can also rename a field when you are creating an anonymous type; the following example renames the UnitPrice field to Price. select new {p.ProductName, Price = p.UnitPrice};
Object initializers with nullable types It is a compile-time error to use a collection initializer with a nullable struct.
Collection Initializers  let you specify one or more element intializers when you initialize a collection class that implements IEnumerable. The element initializers can be a simple value, an expression or an object initializer. By using a collection initializer you do not have to specify multiple calls to the Add method of the class in your source code; the compiler adds the calls. The following examples shows two simple collection initializers:
List digits = new List { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
List digits2 = new List { 0 + 1, 12 % 3, MakeInt() };
The following collection initializer uses object initializers to initialize objects of the Cat class defined in an earlier example. Note that the individual object initializers are enclosed in braces and separated by commas.
List cats = new List{
new Cat(){ Name="Sylvester", Age=8 }, new Cat(){ Name="Whiskers", Age=2}, new Cat() { Name="Sasha", Age=14} };
You can specify null as an element in a collection initializer if the collection's Add method allows it.
List moreCats = new List{
new Cat(){ Name="Furrytail", Age=5 }, new Cat(){ Name="Peaches", Age=4}, null };

Friday, September 25, 2009

New features C# 3.0 :Implicitly Typed Local Variables

Local variables can be given an inferred "type" of var instead of an explicit type. The var keyword instructs the compiler to infer the type of the variable from the expression on the right side of the initialization statement.

The following examples show various ways in which local variables can be declared with var:
// i is compiled as an int
var i = 5;
// s is compiled as a string
var s = "Hello";
// a is compiled as int[]
var a = new[] { 0, 1, 2 };
// expr is compiled as IEnumerable
// or perhaps IQueryable
var expr = from c in customers
where c.City == "London"
select c;
// anon is compiled as an anonymous type
var anon = new { Name = "Terry", Age = 34 };
// list is compiled as List
var list = new List();

It is important to understand that the var keyword does not mean “variant” and does not indicate that the variable is loosely typed, or late-bound. It just means that the compiler determines and assigns the most appropriate type.
The var keyword may be used in the following contexts:
  • On local variables (variables declared at method scope) as shown in the previous example.
  • In a for initialization statement. for(var x = 1; x < 10; x++)
  • In a foreach initialization statement. foreach(var item in list){...}
  • In a using Statement using (var file = new StreamReader("C:\\myfile.txt")) {...}
 The following restrictions apply to implicitly-typed variable declarations:
  • var can only be used when a local variable is declared and initialized in the same statement; the variable cannot be initialized to null, or to a method group or an anonymous function.
  • var cannot be used on fields at class scope.
  • Variables declared by using var cannot be used in the initialization expression. In other words, this expression is legal: int i = (i = 20); but this expression produces a compile-time error: var i = (i = 20);
  • Multiple implicitly-typed variables cannot be initialized in the same statement.
  • If a type named var is in scope, then the var keyword will resolve to that type name and will not be treated as part of an implicitly typed local variable declaration.

using Statement (C#)

using Statement-Defines a scope, outside of which an object or objects will be disposed.
Syntax: using (Font font1 = new Font("Arial", 10.0f)) { }
The using statement allows the programmer to specify when objects that use resources should release them. The object provided to the using statement must implement the IDisposable interface. This interface provides the Dispose method, which should release the object's resources.
A using statement can be exited either when the end of the using statement is reached or if an exception is thrown and control leaves the statement block before the end of the statement.
The object can be declared in the using statement, as shown above, or before the using statement, like this:
Font font2 = new Font("Arial", 10.0f);
using (font2) { // use font2 }
Multiple objects can be used in with a using statement, but they must be declared inside the using statement, like this:
using (Font font3 = new Font("Arial", 10.0f),
font4 = new Font("Arial", 10.0f)) {// Use font3 and font4.}
Example: The following sample shows how a user-defined class can implement its own Dispose behavior. Note that your type must inherit from IDisposable.
using System;
class C : IDisposable
{
public void UseLimitedResource()
{ Console.WriteLine("Using limited resource..."); }
void IDisposable.Dispose()
{ Console.WriteLine("Disposing limited resource."); }
}
class Program
{
static void Main()
{
using (C c = new C())  { c.UseLimitedResource(); }
Console.WriteLine("Now outside using statement.");
Console.ReadLine();
}
}