Explore C# 4’s New Dynamic Types and Named/Optional Parameters

# 4.0 includes a number of enhancements and additions, including:

  1. Support for dynamic lookup
  2. Support for both named and optional parameters
  3. Enhanced COM Interop features
  4. Support for variance

This article takes a look at the first two items in that list, provides examples, and shows how you can take advantage of them in your applications. A future article covers the last two items.

As you may be able to divine from the terms in the list, some of C#’s new features are tied into Microsoft’s new Dynamic Language Runtime (DLR) environment?a new feature of the .NET Framework that enables dynamic languages to reside side-by-side and interoperate with statically typed languages.

Author’s Note: To execute the code examples discussed in this article, you should have Visual Studio 2010 Beta 1 or later installed in your system.

Understanding the DLR

The DLR is built on top of the Common Language Runtime (CLR) and opens the door for a common set of technologies and tools to interoperate inside a common framework. Dynamically typed languages such as Python, Ruby, and JavaScript can reside alongside familiar statically typed .NET languages such as C#, Managed C++, and Visual Basic. The CLR provides a common platform where statically typed languages (e.g. C#, VB) can reside and interoperate, while the DLR sits on top of the CLR and provides a common platform for dynamically typed languages to reside and interoperate.

?
Figure 1. Components of the DLR: The DLR includes a .NET language integration layer, a set of runtime code components, and language binders.

The DLR adds a set of services that facilitate dynamic language implementations on .NET’s managed platform. These services include support for a dynamic type system, a standard hosting model, and fast dynamic code generation. In addition, the DLR lets dynamic and static languages interoperate bi-directionally.

To support the DLR, the .NET Framework 4.0 contains a new System.Dynamic namespace. The Dynamic Language Runtime contains three layers (see Figure 1):

  1. The .NET Language Integration Layer
  2. The Dynamic Language Runtime Code Components
  3. Language Binders

The services the DLR provides include:

  • Dynamic Method Dispatch
  • Dynamic Code Generation
  • Hosting API

With that brief introduction to the DLR, you can move on to explore C#’s new features.

Dynamic Lookup

The introduction of dynamic types to the Common Type System led directly to one of the great new features added to C# 4.0: You longer need to worry about the type of an object when assigning values returned from methods or expressions; the runtime performs the necessary binding for you according to the returned value’s type.

Static and Dynamic Typing

Statically typed languages such as C++, C#, or Java perform type checking at compile time. In contrast, dynamically typed languages such as JavaScript, PERL, and Ruby perform type checks at runtime. C# was originally designed as a language based on strong typing?which is good because the compiler can ensure that types match, catching potential bugs earlier in the development cycle. The change now to include dynamic typing in C# is intended to let you invoke different kinds of objects such as COM, and JavaScript seamlessly.

The var and dynamic keywords

To support dynamic variable declaration, C# 4.0 introduces the dynamic keyword. Both the var and dynamic keywords provide local type inference in C#. You need not specify the data type on the left hand-side of an assignment operator, and the system will bind to the correct type on the fly. However, unlike the dynamic keyword, when you use var you must still specify the type on the right-hand side of an assignment operator. Using the dynamic keyword, you need not specify the type at all: all type binding gets done at runtime.

A Dynamic Typing Example

All this sounds more complicated than it is. Here’s an example. Consider the following three business logic classes, each with its own set of methods.

class ProductBL{   public void ProcessNewProductData()   {      Console.WriteLine("Process method of the ProductBL " +         "class has been called.");   }}class OrderBL{   public void ProcessNewOrderData()   {      Console.WriteLine("Process method of the OrderBL " +          "class has been called.");   }}class CustomerBL{   public void ProcessNewCustomerData()   {      Console.WriteLine("Process method of the CustomerBL " +          "class has been called.");   }}

As you can see, each class has distinct methods. Now, suppose you need to invoke the “process” method on instances of any of these classes on the fly. This type of problem is well-suited to dynamic typing. First, create an enum that contains a list of the business logic instance types.

public enum BusinessLogicObjectType {    ProductBL, CustomerBL, OrderBL };

The following method returns an instance of one of the business logic classes:

public static object GetBusinesLogicInstance(   BusinessLogicObjectType businessLogicObjectType){   switch (businessLogicObjectType)   {      case BusinessLogicObjectType.ProductBL:          return new ProductBL();      case BusinessLogicObjectType.CustomerBL:          return new CustomerBL();      default: return null;   }}

You can now use the dynamic keyword to invoke the appropriate business logic instance on the fly, as shown below:

?
Figure 2. Sample Output: Here’s the output from dynamically invoking one of the business object class methods.
static void Main(string[] args){   dynamic dynamicBLObject = GetBusinesLogicInstance(      BusinessLogicObjectType.ProductBL);   dynamicBLObject.ProcessNewProductData();   Console.Read();}

That’s it! As shown in Figure 2, executing the application displays the message "Process method of the ProductBL class has been called." You can see the complete sample code in Listing 1.

Named and Optional Parameters

Optional parameters, default values and named parameters are more interesting new features. Optional parameters let you avoid having to pass arguments when invoking methods. Default values let you provide any un-passed parameters with default values when invoking the method. Named parameters let you provide arguments using parameter names rather than by their position in the parameter list?meaning you can pass out-of-order named parameters to methods, and they’ll work just fine. Here are some examples.

Consider the following method:

static int Add(int x = 0, int y = 0){   return (x + y);}

As you can see, the parameters x and y have been given default values?the Add() method has default initializers in its parameters list. You can now call Add() without passing any parameters, as shown below:

int result = Add(); 

The preceding line returns 0, because both arguments get initialized to their default values.

Of course, you can also pass values explicitly:

int result = Add(5, 6); // returns 11

Optional parameters should appear at the end of the list in the method arguments; in other words, optional parameters should come last, after all the required parameters in the parameter list have been specified. Therefore, the following method is not valid:

static int Add(int x = 0, int y){   return (x + y);}

If you compile that code, you’ll see the error message “Optional parameters must appear after all required parameters.”

However, you can now also pass values using named arguments, which removes the need to remember the order of parameters. Here’s an example:

int result = Add( y:6, x:5); //returns 11 

Notice that the preceding method call specifies y first, and then x, even though that’s in reverse order from the parameter definitions in the Add() method.

Wrapping Up

The most important of all the new features added to C# 4.0 is the new dynamic keyword, which you can use to create objects even when you don’t know the object type at compile time. You can get more information on the new features of C# 4.0 as well as a few samples of C# 4.0 Beta 1 code samples here.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

Recent Articles: