An Introduction to New Features in C# 5.0
(http://blogs.msdn.com/b/mvpawardprogram/archive/2012/03/26/introduction-of-new-features-in-c-5-0.aspx)
1. C# Evolution MatrixMicrosoft just published a new version of C# : 5.0 beta with CLR version 4.5 (Visual Studio 11 beta).
In order to get a big picture of the whole evolution of C# language, I summarized all the key features
into a C# Evolution Matrix for your reference as below diagram shows:

In C# version 5.0, there are two key features: Async Programming and Caller Information.
2. Async Feature
Two new key words are used for Async feature: async modifier and await operator. Method marked with async modifier is called async method. This new feature will help us a lot in async programming.
For example, in the programming of Winform, the UI thread will be blocked while we use
HttpWebRequest synchronously request any resource in the Internet. From the perspective of user
experience, we cannot interact with the form before the request is done.
private void btnTest_Click(object sender, EventArgs e)
{
var request = WebRequest.Create(txtUrl.Text.Trim());
var content=new MemoryStream();
using (var response = request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
responseStream.CopyTo(content);
}
}
txtResult.Text = content.Length.ToString();
}

In the above example, after we clicked the Test button, we cannot not make any change to the form
before the txtResult textbox shows the result.
In the past, we can also use BeginGetResponse method to send async request as this sample in MSDN
shows:
http://msdn.microsoft.com/zh-cn/library/system.net.httpwebrequest.begingetresponse(v=vs.80).aspx. But it
will takes us a lot effort to realize it.
Now, we can simply use below code to do request asynchronously :
private async void btnTest_Click(object sender, EventArgs e)
{
var request = WebRequest.Create(txtUrl.Text.Trim());
var content = new MemoryStream();
Task responseTask = request.GetResponseAsync();
using (var response = await responseTask)
{
using (var response = await responseTask)
{
using (var responseStream = response.GetResponseStream())
{
Task copyTask = responseStream.CopyToAsync(content);
//await operator to supends the excution of the method until the task
//is completed. In the meantime, the control is returned the UI thread.
await copyTask;
}
}
txtResult.Text = content.Length.ToString();
}
The await operator is applied to the returned task. The await operator suspends execution of themethod until the task is completed. Meanwhile, control is returned to the caller of the suspended
method.
3. Caller Information
Caller Information can help us in tracing, debugging and creating diagnose tools. It will help usto avoid duplicate codes which are generally invoked in many methods for same purpose, such
as logging and tracing.
We could get the below information of caller method :
- CallerFilePathAttribute Full path of the source
file that contains the caller. This is the file path at compile time. - CallerLineNumberAttribute Line number in the
source file at which the method is called. - CallerMemberNameAttribute Method or property
name of the caller.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplicationTest
{
class Program
{
static void Main(string[] args)
{
InsertLog("Main");
MethodB();
Console.ReadLine();
}
static void MethodA()
{
InsertLog("MethodA");
MethodB();
}
static void MethodB(){ }
static void InsertLog(string methodName)
{
Console.WriteLine("{0} called method B at {1}", methodName, DateTime.Now);
}
}
}
In both Main and MethodA methods, method InsertLog is invoked for logging. Now we can change the codes to be as per below lines:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplicationTest
{
class Program
{
static void Main(string[] args)
{
//InsertLog("Main");
MethodB();
Console.ReadLine();
}
static void MethodA()
{
//InsertLog("MethodA");
MethodB();
}
static void MethodB(
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
InsertLog(memberName);
}
static void InsertLog(string methodName)
{
Console.WriteLine("{0} called method B at {1}", methodName,
DateTime.Now);
}
}
}