5,699,997 members and growing! (14,202 online)
Email Password   helpLost your password?
Languages » C# » General     Intermediate License: The Code Project Open License (CPOL)

C# 3.0 Features

By marlongrech

Shows the new language features for C# 3.0
C# (C# 3.0, C#), .NET (.NET, .NET 3.5), Dev

Posted: 20 Dec 2007
Updated: 20 Dec 2007
Views: 19,762
Bookmarked: 71 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
33 votes for this Article.
Popularity: 6.59 Rating: 4.34 out of 5
1 vote, 3.0%
1
0 votes, 0.0%
2
1 vote, 3.0%
3
11 votes, 33.3%
4
20 votes, 60.6%
5
Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report This Article

Introduction

The C# language is getting more good looking than ever before. C# 3.0 is simple the definition of beauty. The new C# compiler is doing a lot of work for us so let us see how we can use it start using these beautiful features.

C# 3.0 Feature List

Let us start with a very handy feature, "Automatic Properties" (I am not sure how this is called but this is how I like to call it :) ). Basically you can declare a property in C# without creating a data member explicitly, the compiler will go ahead and create it for us.

C# 2.0

private string prop;
public string Prop
{
get { return prop; }
set { prop = value; }
}

C# 3.0

public string Prop { get; set; }

As you can see I am not declaring a member; all you have to do is specify what you want with the property (readonly or not).

Object Initializer

In C# 2.0 whenever you had to construct an object and set it's initial state we used to overload the constructor and pass the property values from the constructor. C# 3.0 introduces a new way of doing this via Object Initializers.

So if I had this class

class MyClass
{
private string prop;
public string Prop
{
get { return prop; }
set { prop = value; }
}
}

C# 2.0

MyClass c = new MyClass();
c.Prop = "asdads";

C# 3.0

MyClass c = new MyClass { Prop = "test" };

Collection Initializers

Collection Initializers are similar to Object Initializers yet these allow you to add items inside your collection.

C# 2.0

List<string> list = new List<string>(2);
list.Add("test1");
list.Add("test2");

C# 3.0

List<string> list = new List<string>{"test1", "test2"};

Dictionary Initializers

As the name suggest this is a new way how you can add items in a IDictionary

C# 2.0

IDictionary<string, string> dict = new Dictionary<string, string>(2);
dict.Add("test1", "test1");
dict.Add("test2", "test2");

C# 3.0

IDictionary<string, string> dict = new Dictionary<string, string> { { "key1", "value1" }, { "key2", "value2" } };

Extenstion Methods

This is quite a cool new feature. Basically you can attach methods at compile time to specific types. Lets say for example you want to add a method to the string type. The string class is inside the System.dll and you do not have access to it's source code. What you can do is declare an extenstion method for the specific type (you can also create an extenstion method for an interface and every class that implements that interface will have the method). An extenstion method must be declared as a static method and inside a static class. You have to pass "this" in front of the argument for the method(the type of the argument must be the type you want to extend). Lets try it out

static class StringExtensions
{
public static string AppendMyNameToString(this string value)
{
return value + " Marlon";
}
}

Now I can do the following code.

Console.WriteLine("Hello".AppendMyNameToString());

and the result will be

"Hello Marlon"

LINQ

I will not go into much detail on this topic because it's quite a large subject. If you are interested, visit this url to get more info on LINQ. Basically LINQ is a declerative way how to query data. So instead of being imperative and using loops and if statments you can tell C# what you want and LINQ will go ahead and build that data for you. Let's take for example you have a list of strings and you want to get all strings that start with the letter "s".

string[] list = new string[] { "test", "marlon", "ema" };

C# 2.0

List<string> results = new List<string>();
foreach (string str in list)
if(str.StartsWith("t"))
results.Add(str);

C# 3.0

IEnumerable<string> result = from x in list
where x.StartsWith("t")
select x;

The above code is equivalent to this

IEnumerable<string> result5 = list.Where(a => a.StartsWith("t")).Select(a => a);

The Where and Select methods are Extenstion Method for the IEnumerable<T> interface that are declared in the Enumerable static class. The a => a.StartWith("t") syntax are lambda functions, we will explain this new feature next.

As you can see LINQ is a declerative way how you can query data. The code is more readable. Again I really want to stress this; I am not going into details of LINQ yet this does not imply that LINQ is just this simple example, beleive me LINQ is HUGE. We will also do some more advanced queries later on in the article using orderby, group and joins. So hold on tight ... :)

Anonymous Types and implicit type variables.

Anonymous types are basically types that you do not declare as classes in your code. Basically when you create an anonymous type the compiler will create a class for you (with a very strange name :) ). So you might be saying but if I do not know the name of the type how can I reference it and create a variable of that type. The answer is the implicit type variable aka var. The var is a new keyword in C# that the compiler will change into the name of the type. So YES you will not loose the static typing! You can also use the var in other scenarios to type in less characters when declaring a variable. The anonymous types are really handy when using linq queries to get a data structure out of the query as shown in the demo project (and even later on when discussing grouping in LINQ). So let us create an anonymous type.

var x = new { Property1 = "hello", Property2 = 5 };
Console.WriteLine(x.Property1);
Console.WriteLine(x.Property2.ToString());

Now let's use the anonymous types in a LINQ query to see it's potential

var result3 = from q in testList
where q.TestProperty.StartsWith("T")
select new { Text = q.TestProperty, InnerDataList = q.ListOfData };

foreach (var item in result3)
Console.WriteLine("Text = {0}, Inner List Count = {1}",
item.Text, item.InnerDataList.Count);

Quite cool ee.. :)

Lambda Expressions

In C# 2.0 anonymous methods where given birth. This was quite a cool feature because you do not have to create a method in your class if you are going to use it just once for an event handler or something similar(like a Predicate<T> for instance). Besides you can use any (there are some implications with this yet I will not talk about this today) variable in context of the anonymous method declaration.

C# 2.0

List<string> listOfstrings = new List<string>();
.....
listOfstrings.ForEach(delegate(string s)
{
s.Trim();
});

C# 3.0

listOfstrings.ForEach(str => str.Trim());

As you can see in the above example the lambda syntax is much cleaner. Basically with lambda you can specify what parameters you want to pass by saying x=> now you can do anything with x since x is the parameter that is being passed to you. If you need to pass more than one variable to the lambda you can do so by saying (x, y)=> and if you need to do more than one line of code in the body you can use the { } to do so.

Partial Methods

C# 3.0 introduces partial methods. Basically this is a way how you can define a method in a partial class and implement it in another partial class. This feature is more for designers. For instance the LINQ to SQL designer uses these feature a lot.

partial class Customer
{
public partial void TestPartial();
}

partial class Customer
{
partial void TestPartial()
{
...
}
}

So I guess these are the new features (that I know of!!!) in C# 3.0. I did not go into much details on each feature since every feature deserves a post on itself. Yet as promised I will go into some more LINQ. Again I will do only basic things and I will not go into much details, I will only show how you can use these features.

Sorting with LINQ

You can sort a collection using LINQ very easily

List<int> intList = new List<int>{15,22,1,14,25,96,3,8,91};

var sortQuery = from z in intList
orderby z ascending
select z;

As you can see the orderby keyword forces the collection to sort. (The sorting feature needs to be implemented by the LINQ provider. This sorting for LINQ to object is implemented for all collection)

Grouping in LINQ

Grouping is another cool feature in LINQ to Objects (I say LINQ to objects since there are more than one LINQ provider. There are LINQ to XML, LINQ to SQL and others... Yet I will only use LINQ to Objects in this post). For example imagine that you have a list of numbers and you want to check which one have a remainder when divided by 2.

var groupQuery = from z in intList
group z by z % 2 == 0 into g
select new { Key = g.Key, Numbers = g };
foreach (var item in groupQuery)
Console.WriteLine("Reminder of 2: {0}, Count: {1}", item.Key, item.Numbers.Count());

As you can see here I am using an anonymous type to create a group. the g.Key will be the different results of the group predicate (z % 2 == 0).

Joins in LINQ

Joins are very powerful for when you have relational data. For example imagine that you have a list of customers and a list of orders for those customers. You want to find out the total bill for a customer by summing up all orders for the customer. You can do this very easily with LINQ

Let us prepare some sample data

Customer cust1 = new Customer { CustumerId = 1 };
Customer cust2 = new Customer { CustumerId = 2 };
List<Customer> customers = new List<Customer> { cust1, cust2 };
List<CustomerOrder> orders = new List<CustomerOrder>
{
new CustomerOrder { Customer = cust1, Total = 90 },
new CustomerOrder { Customer = cust1, Total = 190 },
new CustomerOrder { Customer = cust2, Total = 10 }
};

Now let us query this data to join the 2 lists by their relation

var joinQuery = from cust in customers
join order in orders
on cust.CustumerId equals order.Customer.CustumerId
into customerOrders
select new { CustomerId = cust.CustumerId, Total = customerOrders.Sum(custOrder => custOrder.Total) };

Let us print the result....

foreach (var item in joinQuery)
Console.WriteLine("Customer {0} has a total of {1}", item.CustomerId, item.Total);

Conclusion

C# 3.0 is really powerful and makes our life much easier (specially with LINQ). When you combine all these cool features together you get quite a neat way how to implement nice code that is readable and easy to understand. Again I want to point out that I did not go into much detail since the post would have been to large. Hope you enjoyed it...

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

marlongrech


Check out my Blog
http://marlongrech.wordpress.com/

Currently building a WPF Controls library aka AvalonControlsLibrary
http://marlongrech.wordpress.com/avalon-controls-library/

Occupation: Other
Company: Uniblue Systems (www.uniblue.com)
Location: Malta Malta

Other popular C# articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Search Search Messages 
 Layout  Per page   
 Msgs 1 to 25 of 29 (Total in Forum: 29) (Refresh)FirstPrevNext
GeneralLambda example is a bit misleading...memberrohancragg7:26 15 Oct '08  
GeneralVery good indeed.memberPHS2416:11 27 Jun '08  
GeneralVery nicememberSkye Butler7:40 10 Mar '08  
GeneralNice article but...memberYogesh Jagota0:46 13 Jan '08  
AnswerRe: Nice article but...membermarlongrech2:06 28 Jan '08  
GeneralRe: Nice article but...memberYogesh Jagota2:58 28 Jan '08  
GeneralNicememberMartin Surasky6:34 31 Dec '07  
GeneralRe: Nicemembermarlongrech4:23 1 Jan '08  
GeneralThanxmemberMember 186410623:05 25 Dec '07  
GeneralRe: Thanxmembermarlongrech6:43 28 Dec '07  
GeneralNice article but....membersergueis18:15 25 Dec '07  
GeneralRe: Nice article but....membermarlongrech9:58 27 Dec '07  
GeneralExcellent articlememberKarl Agius6:34 24 Dec '07  
GeneralRe: Excellent articlemembermarlongrech5:42 25 Dec '07  
GeneralAnonymous Types and implicit type variables in C# 3.0memberNick Taylor5:15 24 Dec '07  
GeneralRe: Anonymous Types and implicit type variables in C# 3.0membermarlongrech5:42 25 Dec '07  
Generalcoolmembernikitok3:26 24 Dec '07  
GeneralRe: coolmembermarlongrech5:04 24 Dec '07  
GeneralLINQ is new in 3.5memberparadise803:02 24 Dec '07  
GeneralRe: LINQ is new in 3.5membermarlongrech4:53 24 Dec '07  
GeneralGreat article! Little mistakememberYSDen1232:44 22 Dec '07  
GeneralRe: Great article! Little mistakemembermarlongrech4:51 24 Dec '07  
GeneralKudosmemberStefan Z Camilleri23:08 20 Dec '07  
GeneralRe: Kudosmembermarlongrech5:05 24 Dec '07  
GeneralRe: KudosmemberPHS2416:12 27 Jun '08  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 20 Dec 2007
Editor:
Copyright 2007 by marlongrech
Everything else Copyright © CodeProject, 1999-2008
Web07 | Advertise on the Code Project