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

You will need Visual Studio 2010 or higher. (Released April 2010). .NET Framework. 4.0.


Summary:


1) Dynamic binding


Any type declared as dynamic bypasses compile time type checking. The type is assumed to support any operation.


  void TestDynamic()
  {
      // create an anonymous type
      var anon = new { Name = "Richard" };
  
      Output1(anon);
      Output2(anon);
  }
  
  private void Output1(object anon)
  {
      // this will generate a compile time error
      Console.WriteLine(anon.Name);
  }
  
  private void Output2(dynamic anon)
  {
      // this will print 'Richard'
      Console.WriteLine(anon.Name);
  }
  

2) Named and optional arguments


Optional arguements are similar to c++ default parameters.
Named arguments must come after the unnamed ones.


  void LogError(string message, bool showAssert = false, bool logToFile = false)
  {
      // message is required
      // showAssert is optional
  }
  
  void Test()
  {
      // demonstration of optional argument
      LogError("error1"); // assert false, to-file: false
  
      // demonstration of named argument
      LogError("error1", logToFile: true); // assert false, to-file: true
  }
  

3) Generic co- and contravariance


Generic interfaces and delegates can mark their type parameters as co-variant with the keyword [out], and contra-variant with the keyword [in].

covariance [out] allows matching with a more derived (more specific) type.
contravariance [in] allows matching with a less derived (less specific) type.


A covariant example:


  // a covariant interface
  interface IList<out T>
  {
  }
  
  // implementation of IList
  class List<T> : IList<T>
  {
  }
  
  void Main()
  {
      IList<Object> objectList = new List<Object>();
      IList<String> stringList = new List<String>();
  
      // This is a co-variant assignment (to a more derived type)
      // This works because the IList interface is covariant via the out keyword.
      objectList = stringList;
  
      // If the interface is not marked as contravariant, the compiler will report the error
      // Error CS0266  Cannot implicitly convert type 'IList<object>' to 'IList<string>'
  }
  

A contravariant example:


  // a contravariant interface
  interface IList<in T>
  {
  }
  
  // implementation of IList
  class List<T> : IList<T>
  {
  }
  
  void Test()
  {
      // Contravariance [in] allows matching with a less derived type
      IList<String> stringList = new List<object>();
  
      // If the interface is not marked as covariant, the compiler will report the error
      // Error CS0266  Cannot implicitly convert type 'IList<string>' to 'IList<object>'
  }
  

4) Embedded interop types ("NoPIA")


To call a COM object from a .NET assembly, you need an interop assembly.

The interop assembly is a generated assembly that contains the set of types that a particular COM object exposes to .NET.
If an interop assembly is not provided by the component publisher, one can be generated from the command line.
If an interop assembly is provided by the publisher, it is called the Primary Interop Assembly, or PIA. If a PIA is available, it should be used in preference to a generated one.


C# 4.0 allows this COM interop type information to be embedded into the calling assembly, instead of deploying a separate file.

Ads by Google



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

© Richard McGrath