Introduction
With the advent of C#4.0, we have a new friend… Dynamic.
It references objects which happens to or not to exist at runtime. Put in different term, it allows late binding.
Using the code
Let us start with a very basic example
Example 1: Simple Addition
dynamic dynVar = 10;
dynVar += 10;
Console.WriteLine(dynVar);
Output is: 20
Example 2: Simple Concatenation
dynVar += " Hello";
Console.WriteLine(dynVar);
Output is: 10 Hello
But consider this
var varVariable = 10;
varVariable += " Hello";
This will yield a compile time error
Cannot implicitly convert type 'string' to 'int'
However the below works
object obj = 10;
obj += "Hello";
Console.WriteLine(obj);
Reason: It is a specific type inferred from context and does not change type like dynamic does
Example 3:
Consider the below
dynamic dynClass = new MyClass()
{
IntProperty = 1
, StringProperty = "A string property"
,
, StringField = "A string filed"
,
, DecimalField = 10d
};
And
var varClass = new MyClass()
{
IntProperty = 1
,
StringProperty = "A string property"
,
StringField = "A string filed"
,
DecimalField = 10d
};
TestCase1 : Display Valid Property value
Console.WriteLine(dynClass.IntProperty); Using dynamic object
Console.WriteLine(varClass.IntProperty); using var object
Worked with a charm with the output being 1 for each case.
TestCase2 : Display InValid Property value
Console.WriteLine(dynClass.InvalidProperty); Using dynamic object
Compiled fine
Runtime Error: 'DynamicExample.MyClass' does not contain a definition for 'InvalidProperty'
Console.WriteLine(varClass.InvalidProperty); using var object
Complie time error DynamicExample.MyClass' does not contain a definition for 'InvalidProperty' and no extension method 'InvalidProperty' accepting a first argument of type 'DynamicExample.MyClass' could be found (are you missing a using directive or an assembly reference?)
TestCase3 : Display Valid Function Call
Console.WriteLine(dynClass.ValidMethod()); Using dynamic object
Console.WriteLine(varClass.ValidMethod()); using var object
As expected, worked fine with the output being Hello
TestCase4 : Display InValid Function Call
Console.WriteLine(dynClass.InvalidMethod()); Using dynamic object
Runtime error 'DynamicExample.MyClass' does not contain a definition for 'InvalidMethod'
Console.WriteLine(varClass.InvalidMethod()); using var object
Compile time error as expected 'DynamicExample.MyClass' does not contain a definition for 'InvalidMethod' and no extension method 'InvalidMethod' accepting a first argument of type 'DynamicExample.MyClass' could be found (are you missing a using directive or an assembly reference?)
Example 4: Runtime invocation
Consider the below two cases
Case 1
Case 1: Using reflection to invoke member
var type = typeof(DynamicExample.MyClass);
var res1 = type.InvokeMember(
"Add"
, BindingFlags.InvokeMethod
, null
, Activator.CreateInstance(type)
, new object[] { 10, 20 });
Console.WriteLine("Addition of two number using reflection= " + res1);
Case 2
Case 2: Using Dynamic to invoke member
dynamic res2 = ((dynamic)Activator.CreateInstance(typeof(DynamicExample.MyClass))).Add(10, 20);
Console.WriteLine("Addition of two number using dynamic= " + res2);
The output being same in both the cases.
Example 5: Calling Iron Python Function From C# 4.0
Here I will give a short demo as how to call a method written in IronPython 2.6 and making a dynamic invocation to the method from C# environment.
Step 1: Download the latest version of Iron Python from Code Plex
Step 2: Install the software.
Step 3: For this demo I am using “first.py” python file located inside the Tutorial Folder
The file has two methods
a) Add
b) Factorial.
For this demo purpose, let us only invoke the Add method that performs addition of two numbers being supplied as parameters to the method.
Step 4: I am using a console application for the demo purpose. The very first thing we need to do is to add the dlls as shown under
Step 5: The function invocation happens in just three steps as shown below
static void Main(string[] args)
{
var ironPythonRuntime = Python.CreateRuntime();
try
{
dynamic loadIPython = ironPythonRuntime.UseFile("first.py");
Console.WriteLine(
string.Format("Addition result from IronPython method for {0}
and {1} is {2}",100,200, loadIPython.add(100, 200)));
}
catch (FileNotFoundException ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey(true);
}
The very first line
var ironPythonRuntime = Python.CreateRuntime();
loads the Iron Python libraries along with the DLR code needed to execute the python script.
Second line
dynamic loadIPython = ironPythonRuntime.UseFile("first.py");
loads the python script into memory. The significance of the dynamic variable(loadIPython) here is being the fact that Python calls are resolve at runtime.
The last line i.e.
Console.WriteLine(string.Format("
Addition result from IronPython method for {0} and {1}
is {2}", 100,200,
loadIPython.add(100, 200)) );
Is simply to invoke the Python method and to display the result.
Step 6: And here is the output
Example 6: Calling Iron Ruby Function From C# 4.0
Here I will give a short demo as how to call a method written in IronRuby 1.1 and making a dynamic invocation to the method from C# environment.
Step 1: Download the latest version of Iron Ruby from Code Plex
Step 2: Install the software.
Step 3: For this demo I am using add.rb Ruby file which has only one Add method that performs addition of two numbers being supplied as parameters to the method.
Step 4: I am using a console application for the demo purpose. The very first thing we need to do is to add the dlls as show below
Step 5: The function invocation happens in just three steps as shown below
static void Main(string[] args)
{
var ironRubyRuntime = Ruby.CreateRuntime();
try
{
dynamic loadIRuby = ironRubyRuntime.UseFile(@"add.rb");
Console.WriteLine(
string.Format("Addition result from Iron Ruby method for {0} and
{1} is {2}",100, 200, loadIRuby.add(100, 200))
);
}
catch (FileNotFoundException ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey(true);
}
The very first line
var ironRubyRuntime = Ruby.CreateRuntime();
loads the Iron Ruby libraries along with the DLR code needed to execute the python script.
Second line
dynamic loadIRuby = ironRubyRuntime.UseFile(@"add.rb");
loads the Ruby script into memory. The significance of the dynamic variable(loadIRuby) here is being the fact that Ruby calls are resolve at runtime.
The last line i.e.
Console.WriteLine(string.Format
("Addition result from Iron Ruby method for {0}
and {1} is {2}", 100, 200,
loadIRuby.add(100, 200)));
Is simply to invoke the Ruby method and to display the result.
Step 6: And here is the output
References
http://msdn.microsoft.com/en-us/library/dd264736.aspx
Conclusion:
In this short tutorial we have seen how the dynamic keyword helps us in various situations. Having said that, there are some pitfalls of this keyword like runtime checking and henceforth breaks the hallmark of C#’s strong type checking. Hope this tutorial has shed some idea on how, where to use dynamic and also how to invoke IronPython and IronRuby methods from C# 4.0.
Comments on the topic are highly appreciated for the improvement of the topic.
Thanks for reading the article.