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
.
- Let's create a class for
Emails
and Enum
for Email
Type:
public class Emails
{
public Guid guid;
public EmailType emailType;
public string email;
public Emails(Guid guid, EmailType emailType, string email)
{
this.guid = guid;
this.emailType = emailType;
this.email = email;
}
}
- Create an
Enum
of an Email
Type that is used in the above class to get an EmailType
.
public enum EmailType
{
General,
Organization,
Collected
}
Main
method which describes the original reference type object
, System.Object
object and dynamic
object.
static void Main(string[] args)
{
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);
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);
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