C# - what's new in C# 3.0?

You will need Visual Studio 2008 or higher. (Released November 2007). .NET Framework. 3.5.


Summary:


1) Implicitly typed local variables


The var keyword can be used in place of a type name when the compiler has enough information to determine the type.


  // the new way
  var num = 3;
  var greeting = "Hello";
  var odd = new int[] {1,3,5,7};
  var b = 1==1;
  
  // the old way
  int num = 3;
  string greeting = "Hello";
  int[] odd = new int[] {1,3,5,7};
  bool b = 1==1;
  

1) Object initializers


Provides a concise syntax for creating an object and setting its properties.


  // the new 'object initializer' syntax
  var person = new Person() { Name = "Richard", Age = 44 };
  // or
  var person = new Person { Name = "Richard", Age = 44 };
  
  
  // the old way. using explicit property assignment
  var person = new Person();
  person.Name = "Richard";
  person.Age = 44;
  
  
  // the old way. using a parameterized constructor
  var person = new Person("Richard", 44);
    
  class Person
  {
      public string Name { get; set; }
      public int Age{ get; set; }
  }
  

2b) Collection initializers


Provides a concise syntax for creating a collection and populating it.


  var even = new int[] { 2, 4, 6, 8, 10 };
  
  var philosophers = new List
  {
      new Person { Name = "Socrates", Age = 71 },
      new Person { Name = "Plato", Age = 80 },
      new Person { Name = "Aristotle", Age = 62 }
  };
  

3) Auto-implemented properties


Auto properties encapsulate a property and a compiler generated backing field.


  // new way. the backing field is compiler generated
  class Person
  {
      public string Name { get; set; }
      public int Age { get; set; }
  }
  
  // old way. the backing field is specified
  class Person
  {
      private string _name;
      private int _age;
  
      public string Name { get { return _name; } set { _name = value; } }
      public int Age { get { return _age; } set { _age = value; } }
  }
  

4) Anonymous types


Just like anonymous methods, an anonymous type is declared without a type name.


  var person = new
  {
      Name = "Richard",
      Age = 44
  };
  
  var name = person.Name;
  var age = person.Age;
  

Anonymous types are especially useful with LINQ to SQL to create a strongly typed result set without having to declare a new type.


  var londonOrders =
      from o in db.Orders
      where o.Customer.City == "London"
      select new { Customer = o.Customer, Order = o };
  

5) Extension methods


Extension methods add new methods to an existing type.


  public static class StringExtensions
  {
      public static bool IsLowerCase(this string str)
      {
          return str.ToLower() == str;
      }
  }
  
  void TestExtensionMethod()
  {
      var str = "hello";
      var islower = str.IsLowerCase();
  }
  

6) Query expressions


Query expresssions provide a SQL-like language for manipulating objects.


  var numbers = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
  
  var squared = from x in numbers
                  where x%2==1
                  select x * x;
  
  Console.WriteLine("Odd Squared: {0}", String.Join(",", squared));
  

  Odd Squared: 1,9,25,49,81

7) Lambda expressions


Lambda expressions provide a concise syntax for creating anonymous methods.


  var t = new System.Timers.Timer();
  t.Interval = 1000;
  
  // using an anonymous function
  t.Elapsed += delegate(object sender, ElapsedEventArgs e)
  {
      Console.WriteLine("Tick at {0}", e.SignalTime);
  };
  
  // using a lambda expression
  t.Elapsed += (sender, e) => Console.WriteLine("Tick at {0}", e.SignalTime);
  
  t.Start();
  

8) Expression trees


Expression trees permit lambda expressions to be represented as data structures instead of code.
This allows lambda expressions to be modified by other code at runtime.
LINQ providers use expression trees to optimize queries (manipulating them as data) before running them. This is particularly important when the underlying medium is relatively slow. E.g. a database.


  // Code
  Func<int, int> f = x => x + 1;
  // Data
  Expression<Func<int, int>> e = x => x + 1;
  
  var compiled = e.Compile();
  var val = compiled(1);
  
  Console.WriteLine("Val is: {0}", val);
  

9) Partial methods


A partial method has no implementation. It is a placeholder. If the method is not implemented with another partial method declaration, it will be removed by the compiler.
A partial method must be declared within a partial class.


  // Program.cs
  partial class Program
  {
      static void Main(string[] args)
      {
          MyPartialMethod();
      }
  
      // a placeholder. no implementation
      partial void MyPartialMethod();
  }
  
  // Program_impl.cs
  partial class Program
  {
      partial void MyPartialMethod()
      {
          Console.WriteLine("Hello");
      }
  }
  

  Hello
  

Ads by Google



Ask a question, send a comment, or report a problem - click here to contact me.

© Richard McGrath