Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Dynamic Keyword In C# 4.0 - Part 3

0.00/5 (No votes)
19 Apr 2011 2  
Difference between Dynamic and Object type

Introduction

In C#, all types, predefined, user-defined, reference types and value types, inherit directly or indirectly from Object. We can assign values of any type to variables of typeobject. When a value of any type converted to object is called Boxing and vice versa (Unboxing), this is not the case in dynamic (it stores metadata about the dynamic calls at compile time and applies it to calls at runtime). Let’s take a function that returns System.Object, an instance that can be cast to nearly anything. So let’s determine how using dynamic is better than using System.Object?

As we discussed in part 1, in C#, the actual type behind the variable that is declared dynamic is resolved at runtime and a compiler simply assumes that the object in a variable declared dynamic just supports any operations (DO NOT CARE WHAT TO ASSIGN).

It means in dynamic, we can call a method on an object that is expected to be there at runtime, while in object type code will not get compiled if we use a method name of an object directly. To make it available, we need to use casting or reflection in order to work with object types.

Let’s take an example which clearly describes the difference between object and dynamictypes.

  1. Let's create a class for Emails and Enum for Email Type:
    /// <summary>
    /// Email information collection class
    /// </summary>
    public class Emails
    {
        /// <summary>
        /// Email id
        /// </summary>
        public Guid guid;
     
        /// <summary>
        /// Email type
        /// </summary>
        public EmailType emailType;
        
        /// <summary>
        /// Email name
        /// </summary>
        public string email;
      
        /// <summary>
        /// Initializes instance of an Emails class
        /// </summary>
        /// <param name="guid">Email id</param>
        /// <param name="emailType">Email type</param>
        /// <param name="email">Email name</param>
        public Emails(Guid guid, EmailType emailType, string email)
        {
             this.guid = guid;
             this.emailType = emailType;
             this.email = email;
        }
    }
  2. Create an Enum of an Email Type that is used in the above class to get an EmailType.
    /// <summary>
    /// Email type
    /// </summary>
    public enum EmailType
    {
         /// <summary>
         /// General
         /// </summary>
         General,
        
         /// <summary>
         /// Organization
         /// </summary>
         Organization,
      
         /// <summary>
         /// Collected
         /// </summary>
         Collected
    }
  3. Main method which describes the original reference type object, System.Object object and dynamic object.
    static void Main(string[] args)
    {
    // Reference class (Emails) itself
    Emails emails = new Emails(new Guid(), 
    	EmailType.General, "sanjay.patolia@patni.com");
    Console.WriteLine("Email : {0}, Email Type : {1}, Email Id : {2}", 
    emails.email, emails.emailType, emails.guid);
     
    // Reference type object (Emails) to object type
    // Needs to explicit casting in order to make it work
    // Will be resolved at compile time.
    object objectEmails = new Emails(new Guid(), 
    	EmailType.General, "sanjay.patolia@patni.com");
    Console.WriteLine("Email : {0}, Email Type : {1}, Email Id : {2}", 
    (objectEmails as Emails).email, (objectEmails as Emails).emailType, 
    (objectEmails as Emails).guid);
     
    // Reference type object (Emails) to dynamic type
    // Use any member of Emails class
    // Will be resolved at run time.
    dynamic dynamicEmails = new Emails(new Guid(), 
    EmailType.General, "sanjay.patolia@patni.com");
    Console.WriteLine("Email : {0}, Email Type : {1}, Email Id : {2}", 
    dynamicEmails.email, dynamicEmails.emailType, dynamicEmails.guid);
     
    Console.ReadKey(true);
    }

In Main

Initially, we are going to create an object of a class Emails which is assigned to Emails itself and printing the member values of Emails by accessing the members using (.) Dot operator directly.

Secondly, we are creating an object of Emails class and assigning it to the object type and printing the member values of Emails class by casting the objectEmails from object type to Emails type. Here, we cannot directly say that (objectEmails.Email) this statement will not get compiled, because the member Email will not be available though it is assigned to objectEmails. We need to cast it to Emails type in order to make all the members of Emails class available, while this is not the case in dynamic.

In dynamic, as we discussed in part 1, the whole operation will be resolved at runtime, so we can assign or we can call any member of the Emails class, it will not generate a compile time error here. It checks at runtime whether the called method or member is available or not. It will throw an error at runtime, if it does not find the called member at runtime.

Array of Dynamic

dynamic[] emailsCollection = new dynamic[3];
Console.WriteLine(emailsCollection.GetType());

When we say, emailsCollection, it gives a list of members.

Now the question is why it shows members because dynamic does not show any members.

The answer is, it is an array of dynamic so it is not exactly a dynamic object, it is Sytem.Object[] when we declare the above dynamic statement.

Thus, an object type needs some reflection or explicit casting in order to make an object available. While in dynamic, runtime it checks the members, so we can call any members of assigned object without casting or any reflection method.

History

  • 19th April, 2011: Initial post

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here