By
Zach Smith
Monday, November 27 2006 09:34 AM
URL:
http://www.zdnetasia.com/builder/program/java/0,39045537,61968897,00.htm
This article will explain several key changes in C# 3.0 which is scheduled for release in 2007.
1. Implicitly typed local variables
C# 3.0 introduces a new keyword called "var". This keyword allows a
developer to declare a variable without explicitly declaring its type. For
instance, using the var keyword to instantiate a string
would look something like this:
varmyData = "This is my data";
Notice
that there is no mention that the myData variable will be a string, even though that would be
required in C# 2.0.
Even
though var allows you to do implicit type
declaration, it does not degrade the strongly typed nature of C#. The var keyword only works when declaring the variable, and
once the variable is declared the variable's type is inferred and assigned. You
cannot change the type of a variable declared with var at a later point in the code.
For
instance, this code will not work:
varmyDate = DateTime.Now;
myDate = "Hello.";
An
interesting result of the var keyword is that it enables developers to do away with the redundant
entry of a variable's type. For instance, to declare a Customer object in C#
2.0, I would type:
Customer myCustomer = new Customer();
Using
the new var keyword, this can be converted to:
varmyCustomer = new Customer();
Another
interesting feature of the var keyword is its ability to free you from having to change calls to a
method that return a certain type of object. For instance, in C# 2.0, if you
needed to call a method that returned a Customer object, you would write:
Customer myCustomer = GetByName("Zach");
If at
some point the GetByName method returns something other than
a Customer object, this code would fail to compile. However, if you use the var keyword you can be freed from worrying about the
type of object returned from GetByName:
varmyData = GetByName("Zach");
Now
the GetByName method could be changed to return a
Person object and the method call would still be valid, due to the fact that
the var keyword is being utilized.
2. Extension methods
In C#
you cannot inherit and extend types marked with the access modifier of "sealed."
In C# 3.0, extension methods allow you to extend any class, even classes marked
as sealed. For instance, if we wanted to add a NoSpaces()
method to the string class, we would define an extension method similar to Listing A.
Listing A
namespaceMyExtensionMethods
{
public static class Extension
{
public static void NoSpaces(this string data)
{
return data.Replace(" ", "");
}
}
}
When
this extension method is imported into a class, developers will be able to call
NoSpaces() on
any string contained within the class.
The
first parameter of the extension method is what determines the type that the
extension method will be available from. In this case, "this string data",
indicates that the extension method should be applied to the string class. If
the extension method was declared with "this object data" as the
first parameter, then the method would be available from every object.
To indicate
that you would like to import extension methods, simply include a using directive for their namespace. For
instance, to use the method described above, a using MyExtensionMethods directive is required in your class
file: (Listing B)
Listing B
usingMyExtensionMethods;
namespace MyNamespace
{
public class MyClass
{
public MyClass()
{
string data = "this is my data";
//nospaces will contain "thisismydata".
string nospaces = data.NoSpaces();
}
}
}
Note
that extension methods take a lower precedence than instance methods. So if an
instance method has the same signature as an extension method, the instance
method will be executed.
3. Object initializers
In C# 2.0 many developers found themselves creating a number of constructors to set a
certain property's value as the object was instantiated. An example of this is
below:
- Class accessing Customer:
Customer myCustomer = new Customer("Zach", "Smith");
- Customer class constructors:
public Customer(string firstName, string lastName) : this()
{
this.FirstName = firstName;
this.LastName = lastName;
}
public Customer()
{
}
C# 3.0
introduces a new way to initialize objects that allows you to set any property's
value when you instantiate the object. For instance, the code block above can
be written like this in C# 3.0:
- Class accessing Customer:
Customer myCustomer = new Customer{FirstName = "Zach", LastName = "Smith" };
- Customer class constructors:
public Customer()
{
}
In the
C# 3.0 code, there is no constructor that corresponds to the way I instantiated
the object. This prevents developers from having to create a different
constructor for each different set of properties that need to be set.
A side
effect of this is that code becomes easier to read. For instance while it is
obvious that the following line of code is instantiating a Car object, it is
not obvious what the variables are:
Car car = new Car(18, 10, 550);
This
line of code is easier to read at a glance, although it does require more
keystrokes:
Car car = new Car { WheelDiameter = 18, WheelWidth = 10, Horsepower = 550 };
4. Anonymous types
While
C# 2.0 introduced anonymous methods, C# 3.0 introduces anonymous types.
Anonymous types are similar to anonymous methods in that they are declared
in-line and have no formal name. To declare an anonymous type you combine the
new Object Initializer
and Implicitly Typed Local Variable
concepts described above. Below is an example of an anonymous type:
varmyType = new { Length = 79, Width = 30 };
The
scope of the anonymous type is the same as with any other declared variable.
For instance, the cobra instance in the following code block is only available
in the Speed function block:
private void Speed()
{
var cobra = new { Horsepower = 550, Torque = 570 };
}
If an
anonymous type is instantiated while another anonymous type is in scope, and
they both have the same signatures, the second type will automatically take the
first type's type. For instance, in this code block, both cobra and mustang are
the same anonymous type, and can be set to one another:
private void Speed()
{
var cobra = new { Horsepower = 550, Torque = 570 };
var mustang = new { Horsepower = 300, Torque = 300 };
mustang = cobra; //or you could say cobra = mustang
}
5. LINQ
In previous versions of C# developers used many different query languages to
access different data sources. For example, to query an XML document the
developer would use XPath, and to query a SQL
database, the developer would use SQL. This has worked well in the past, and
continues to be the dominant method of accessing disparate data. However, there
are some drawbacks to this approach.
One
significant disadvantage is that developers must write the queries in a
different language than the one they are currently working in (i.e. SQL or XPath). Another drawback is that when implementing some
query languages, such as SQL, the developer must develop mapping code to
translate the results of the query into usable C# business objects.
For C#
3.0, Microsoft has introduced a new technology called Language Integrated Query
(LINQ). Using LINQ, developers are able to write standard queries that can
search any IEnumerable<T> data source. So
instead of using TSQL to access a MS SQL database, and XPath
to access an XML file, they use LINQ.
The
following (Listing C) is an example
of a LINQ query that returns all the customers who have an OrderCount greater than 10:
Listing C
using System;
using System.Query;
using System.Collections.Generic;
public class SampleClass
{
static void Main()
{
List<Customer> customers = GetCustomers();
//Write our query to retrieve customers who have more than
// 10 orders.
IEnumerable<Customer> queryResult = from customer in customers
where customer.OrderCount > 10
orderbycustomer.ID
select customer;
}
}
Unlike
SQL or XPath, LINQ queries are written in C#, not a third
party language. This enables the queries to be type safe, and there is no need
for developers to write mapping code to map the data returned from the query to
a C# object. Mapping is handled automatically by the LINQ API.
Basically,
the LINQ project acts as a built in ORM solution. As such, its scope is very
broad, and there is a wealth of information on MSDN describing its capabilities.
To read more about it, go to the LINQ
homepage.
On the horizon
As you
can see, some exciting new features are coming with C# 3.0. Microsoft has
scheduled the C# 3.0 release to coincide with that of Visual Studio 2007, which
has a rumored release date of Q4 2007.