Preview of What's New in C# 3.0

Introduction 

This article discusses about following new enhancements expected in C# 3.0. Microsoft has given a sneak preview of what to expect in this version. 

The expected new enhancements are as follows: 

  • Implicitly Typed Local Variables
  • Anonymous Type
  • Extension Methods
  • Object and collection Initializers
  • Lambda expressions
  • Query expressions
  • Expression Trees 

Implicitly Typed Local Variables 

C# 3.0 introduces a new keyword called "var". It allows you to declare a new variable, whose type is implicitly inferred from the expression used to initialize the variable.  

For Example: 

var i = 10; 

The preceding line initializes the variable i to value 1 and gives it the type of integer. Note that "i" is not strongly typed to an integer - it is not an object or a VB6 variant, nor does it carry the overhead of an object or a variant. 

In order to use var implicitly typed local variable we have follow certain steps. 

  • var keyword requires that we have to put the assignment on the same line as the declaration.
  • Initializer has to be an expression, not an object or collection initializer and it cannot be null. 

Note: If multiple declaration exist on the same variable, they must all evaluate to the same type at compile time.

var intArr = new[] {1,2,3,4,5}; 

Anonymous Type

C# 3.0, this new feature gives you the flexibility to create an instance of a class without having to write code for the class.

For Example:

new {name="xyz", address="King street, Chicago", state="IL", zipcode="53703"};

The above line of code, with the help of the new keyword, give you a new types that has four properties like name, address, state, zipcode. Behind the scene, the C# compiler would create a class that looks like as follows:

class _Anonymous1

{

    private string _name = "xyz";

    private string _address = "King street, chicago";

    private string _state = "IL";

    private string _zipcode = "53703";

 

    private string name { get { return _name; } set { _name = value; } }

    private string address { get { return _address; } set { _address = value; } }

    private string state { get { return _state; } set { _state = value; } }

    private string zipcode { get { return _zipcode; } set { _zipcode = value; } }
}
 

Now you have a class, but you still need something to hold an instance of the above class. This is where the "var" keyword comes in handy.  

var objtest = new {name="xyz", address="King street, Chicago", state="IL", zipcode="53703"};         

Extension Methods 

Extension methods enable you to extend various types with additional static methods. Extension methods can be declared only in static classes and are identified by the keyword "this" as a modifier on the first parameter of the method.  

For Example:

public static int ToInt32(this string s)

{ 

    return Convert.ToInt32(s); 

} 

string s = "10"; 

int i = s.ToInt32();

Object and Collection Initializers 

C# 3.0 is expected to allow you to include an initializer that specifies the initial values of the members of a newly created object or collection. This enables you to combine declaration and initialization in one step. 

For instance, if you defined a CoOrdinate class as follows: 

public class CoOrdinate
{
    public int x;
    public int y;
}

You then could declare and initialize a CoOrdinate object using an object initializer, like this: 

var myCoOrd = new CoOrdinate{ x = 0, y= 0} ; 

Similarly, you should easily be able to give values to collections in a rather concise and compact manner in C# 3.0. For instance, the following C# 2.0 code: 

List<string> animals = new List<string>(); 

animals.Add("monkey"); 

animals.Add("donkey"); 

animals.Add("cow"); 

animals.Add("dog"); 

animals.Add("cat");

Now can be shortened to simply: 

List<string> animals = new List<string>
{
"monkey", "donkey", "cow", "dog", "cat" } ;

Lambda Expressions

C# 1.x allowed you to write code blocks in methods, which you could invoke easily using delegates. Delegates are definitely useful, and they are used throughout the framework, but in many instances you had to declare a method or a class just to use one. Thus, to give you an easier and more concise way of writing code, C# 2.0 allowed you to replace standard calls to delegates with anonymous methods. The following code may have been written in .NET 1.1 or earlier:

class Program

{

    delegate void DemoDelegate();

    static void Main(string[] args)

    {

        DemoDelegate myDelegate = new DemoDelegate(SayHi);

        myDelegate();

    }

    void SayHi()

    {

        Console.Writeline("Hello World!!");

    }
}

In C# 2.0, using anonymous methods, you could rewrite the code as follows:

 

class Program

{

    delegate void DemoDelegate();

    static void Main(string[] args)

    {

        DemoDelegate myDelegate = delegate()

        {

            Console.Writeline("Hello World!!");

        };

        myDelegate();

    }
}

Whereas anonymous methods are a step above method-based delegate invocation, lambda expressions allow you to write anonymous methods in a more concise, functional syntax.

You can write a lambda expression as a parameter list, followed by the => token, followed by an expression or statement block. The above code can now be replaced with the following code:

class Program

{

    delegate void DemoDelegate();

    static void Main(string[] args)

    {

        DemoDelegate myDelegate = () => Console.WriteLine("Hello World!!") ;

        myDelegate();

    }
}

Although Lambda expressions may appear to be simply a more concise way of writing anonymous methods, in reality they also are a functional superset of anonymous methods. Specifically, Lambda expressions offer the following additional functionality:

  • They permit parameter types to be inferred. Anonymous methods will require you to explicitly state each and every type.
  • They can hold either query expressions (described in the following section) or C# statements.
  • They can be treated as data using expression trees (described later). This cannot be done using Anonymous methods.  

Query Expressions

Even though further enhancements may be introduced in the coming months as C# 3.0 matures, the new features described in the preceding sections make it a lot easier to work with data inside C# in general. This feature, also known as LINQ (Language Integrated Query), allows you to write SQL-like syntax in C#.

For instance, you may have a class that describes your data as follows:

public class CoOrdinate
{
    public int x;
    public int y;
}

You now could easily declare the logical equivalent of a database table inside C# as follows:

// Use Object and collection initializers

List<CoOrdinate> coords = ... ;

And now that you have your data as a collection that implements IEnumerable<T>, you easily can query this data as follows:

var filteredCoords =
from c in coords
where x == 1
select (c.x, c.y)

In the SQL-like syntax above, "from", "where", and "select" are query expressions that take advantage of C# 3.0 features such as anonymous types, extension methods, implicit typed local variables, and so forth. This way, you can leverage SQL-like syntax and work with disconnected data easily.

Each query expression is actually translated into a C#-like invocation behind the scenes. For instance, the following:

where x == 1

Translates to this:

coords.where(c => c.x == 1)

As you can see, the above looks an awful lot like a lambda expression and extension method. C# 3.0 has many other query expressions and rules that surround them.

Expression Trees

C# 3.0 includes a new type that allows expressions to be treated as data at runtime. This type, System.Expressions.Expression<T>, is simply an in-memory representation of a lambda expression. The end result is that your code can modify and inspect lambda expressions at runtime.

The following is an example of an expression tree:

Expression<DemoDelegate> filter = () => Console.WriteLine("Hiya!!") ;

With the above expression tree setup, you easily can inspect the contents of the tree by using various properties on the filter variable.
 

I hope this article is useful, C# 3.0 offers incredible new features that make your work as an application developer and architect a lot easier, and yet it remains a programming language that lends itself to stricter and cleaner architecture.  

I am not a right person to take credit for this article, I just read from Microsoft and developer.com site and I shared here.


Similar Articles