Click here to Skip to main content
13,200,202 members (53,633 online)
Click here to Skip to main content
Add your own
alternative version


92 bookmarked
Posted 20 Dec 2007

C# 3.0 Features

, 20 Dec 2007
Rate this:
Please Sign up or sign in to vote.
Shows the new language features for C# 3.0


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

C# 3.0 Feature List

Let us start with a very handy feature, "Automatic Properties" (I am not sure what 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 its 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);
C# 3.0
List<string> list = new List<string>{"test1", "test2"}; 

Dictionary Initializers

As the name suggests, this is a new way by which you can add items in an 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" } };

Extension Methods

This is quite a cool new feature. Basically you can attach methods at compile time to specific types. Let's 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 its source code. What you can do is declare an extension method for the specific type (you can also create an extension method for an interface and every class that implements that interface will have the method). An extension 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). Let's try it out:

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

Now I can do the following code:


And the result will be:

"Hello Marlon" 


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 information on LINQ. Basically LINQ is a declarative way  to query data. So instead of being imperative and using loops and if statements, 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)
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 Extension Methods 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 declarative way by which 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, believe 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 lose 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 };

Now let's use the anonymous types in a LINQ query to see its 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 were 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) 
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 in which 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 features 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 detail 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 detail. 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 collections).

Grouping in LINQ

Grouping is another cool feature in LINQ to Objects (I say LINQ to objects since there is 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 has 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);


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 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 too large. Hope you enjoyed it...


  • 20th December, 2007: Initial post


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


About the Author

Other Uniblue Systems (
Malta Malta
Check out my Blog

Currently building a WPF Controls library aka AvalonControlsLibrary

You may also be interested in...


Comments and Discussions

AnswerObject Initializers Pin
Wisen Technologies18-Dec-12 1:45
groupWisen Technologies18-Dec-12 1:45 
Generalcool Pin
SudhakarReddyK4-Nov-09 1:55
memberSudhakarReddyK4-Nov-09 1:55 
GeneralLambda example is a bit misleading... Pin
rohancragg15-Oct-08 6:26
memberrohancragg15-Oct-08 6:26 
GeneralRe: Lambda example is a bit misleading... Pin
DreamwithinDream26-Feb-12 21:56
memberDreamwithinDream26-Feb-12 21:56 
GeneralVery good indeed. Pin
PHS24127-Jun-08 5:11
memberPHS24127-Jun-08 5:11 
GeneralVery nice Pin
Skye Butler10-Mar-08 6:40
memberSkye Butler10-Mar-08 6:40 
GeneralNice article but... Pin
Yogesh Jagota12-Jan-08 23:46
memberYogesh Jagota12-Jan-08 23:46 
AnswerRe: Nice article but... Pin
marlongrech28-Jan-08 1:06
membermarlongrech28-Jan-08 1:06 
GeneralRe: Nice article but... Pin
Yogesh Jagota28-Jan-08 1:58
memberYogesh Jagota28-Jan-08 1:58 
GeneralNice Pin
Martin Surasky31-Dec-07 5:34
memberMartin Surasky31-Dec-07 5:34 
GeneralRe: Nice Pin
marlongrech1-Jan-08 3:23
membermarlongrech1-Jan-08 3:23 
GeneralThanx Pin
Member 186410625-Dec-07 22:05
memberMember 186410625-Dec-07 22:05 
GeneralRe: Thanx Pin
marlongrech28-Dec-07 5:43
membermarlongrech28-Dec-07 5:43 
GeneralNice article but.... Pin
sergueis25-Dec-07 17:15
membersergueis25-Dec-07 17:15 
GeneralRe: Nice article but.... Pin
marlongrech27-Dec-07 8:58
membermarlongrech27-Dec-07 8:58 
GeneralExcellent article Pin
Karl Agius24-Dec-07 5:34
memberKarl Agius24-Dec-07 5:34 
GeneralRe: Excellent article Pin
marlongrech25-Dec-07 4:42
membermarlongrech25-Dec-07 4:42 
GeneralAnonymous Types and implicit type variables in C# 3.0 [modified] Pin
Nick Taylor24-Dec-07 4:15
memberNick Taylor24-Dec-07 4:15 
Hey Marlon,

I noticed that when you were describing "Anonymous Types and implicit type variables", that this looks almost like JavaScript. Do you know if C# 3.0 got some inspiration from JavaScript?

C# 3.0
var x = new { Property1 = "hello", Property2 = 5 };

var x = { Property1: "hello", Property2: 5 };


GeneralRe: Anonymous Types and implicit type variables in C# 3.0 Pin
marlongrech25-Dec-07 4:42
membermarlongrech25-Dec-07 4:42 
Generalcool Pin
nikitok24-Dec-07 2:26
membernikitok24-Dec-07 2:26 
GeneralRe: cool Pin
marlongrech24-Dec-07 4:04
membermarlongrech24-Dec-07 4:04 
GeneralLINQ is new in 3.5 Pin
paradise8024-Dec-07 2:02
memberparadise8024-Dec-07 2:02 
GeneralRe: LINQ is new in 3.5 Pin
marlongrech24-Dec-07 3:53
membermarlongrech24-Dec-07 3:53 
GeneralGreat article! Little mistake Pin
YSDen12322-Dec-07 1:44
memberYSDen12322-Dec-07 1:44 
GeneralRe: Great article! Little mistake Pin
marlongrech24-Dec-07 3:51
membermarlongrech24-Dec-07 3:51 
GeneralKudos Pin
Stefan Z Camilleri20-Dec-07 22:08
memberStefan Z Camilleri20-Dec-07 22:08 
GeneralRe: Kudos Pin
marlongrech24-Dec-07 4:05
membermarlongrech24-Dec-07 4:05 
GeneralRe: Kudos Pin
PHS24127-Jun-08 5:12
memberPHS24127-Jun-08 5:12 
GeneralAwesome Article! Pin
thebossedgar20-Dec-07 13:29
memberthebossedgar20-Dec-07 13:29 
GeneralRe: Awesome Article! Pin
marlongrech24-Dec-07 4:06
membermarlongrech24-Dec-07 4:06 
GeneralThanks! Pin
Karl Shifflett20-Dec-07 11:59
memberKarl Shifflett20-Dec-07 11:59 
GeneralRe: Thanks! Pin
marlongrech24-Dec-07 4:08
membermarlongrech24-Dec-07 4:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.171020.1 | Last Updated 20 Dec 2007
Article Copyright 2007 by marlongrech
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid