Click here to Skip to main content
15,884,425 members
Articles / Programming Languages / C# 4.0

An introduction to Expando Object- Dotnet 4.0

Rate me:
Please Sign up or sign in to vote.
2.14/5 (13 votes)
26 Oct 2010CPOL3 min read 35.9K   230   12   7
This short article will highlight upon some of the features of Expando Object

Introduction

One more addition to the dotnet 4.0 framework is the Expando object. It is defined in the System.Core assembly and belongs to System.Dynamic namespace.

Intellisense speaks of Expando object as

1.jpg

Expando Object – An Inside View

A detailed look inside the Expando Object reveals the following

2.jpg

The Expando Class cannot be inherited as it is Sealed. It implements six different interfaces. Out of which the below two needs special attention

IDynamicMetaObjectProvider

We know that any object that can have its operations bound at runtime must implement the IDynamicMetaObjectProvider. So is the Expando object.

Hence dynamic dyn = new ExpandoObject(); is a perfectly valid statement.

INotifyPropertyChanged

Whenever a new member is added or modified, the class raises the PropertyChange Event.

Using the code

Example 1: Adding members

Consider the below program

dynamic dyn = new ExpandoObject();
//Members additon
dyn.Member1 = "Some Member";
dyn.Member2 = 2;
Console.WriteLine(dyn.Member1);
Console.WriteLine(dyn.Member2);

Simply we added two members to our ExpandoObject. Really simple.

Example 2: Reading and Writing from Expando Collection

This code piece will show how we can assign values to an Expando Collection

List<expandoobject /> expandoList = new List<expandoobject />();

//Writing to Expando Collection
for (int i = 2; i --> 0;)
{
  dynamic dynObject = new ExpandoObject();
  dynObject.Prop1 = i;
  dynObject.Prop2 = "String Property" + i;                
  dynObject.Prop3 = AddDictionaryObject (i);
  expandoList.Add(dynObject);
}

//Adding a dictionary object
private static Dictionary<int, /> AddDictionaryObject(int i)
{
   Dictionary<int, /> dict = new Dictionary<int, />();
   dict.Add(i, "Value" + i.ToString());
   return dict;
}

First we are instantiating a new ExpandoObject collection.

List<expandoobject> expandoList = new List<expandoobject>();

Then by using the new “Goes To” operator, we have populated two items into the Collection.

The line dynamic dynObject = new ExpandoObject(); ensures that the ExpandoObject is assigned to the dynamic object and henceforth we can add properties to it dynamically which the DLR will check at runtime. We also have a property(here Prop3) which is of type Dictionary < int, string >

The code is pretty straight forward.

The next part shows how to READ values from the Expando Collection just created

//Reading from Expando Collection

foreach (dynamic d in expandoList)
{                
   Console.WriteLine("Reading Collection {0} Values", d.Prop1);
   Console.WriteLine("Prop1 value is:   {0}",d.Prop1);
   Console.WriteLine("Prop2 value is:   {0}", d.Prop2);
   foreach (dynamic dic in d.Prop3)
   {
     Console.WriteLine("The key is {0} and it's value is {1}",dic.Key,dic.Value);
   }

  Console.WriteLine(Environment.NewLine);
  Console.WriteLine("-----------------------------------------------------------");
}

As can be understandable that we are looping through the Expando Collection and since every item is of type dynamic, we can simply call the Property name. However, whether the property is valid or not will be checked at runtime.

Example 3: Adding Action and Func delegates

Consider the below

Case 1: Add Action Delegate for a Callback

dynamic dynObj= new ExpandoObject();

//Add Action Delegate
dynObj.Action = new Action(() =>
{
   Console.WriteLine("Helo From Action Delegate");
 });
//Invoke the Action method
dynObj.Action();

Nothing much so..Simply assigning the Action delegate at runtime and Invoking the same for a simple callback.

Case 2: Add Func Delegate for a Callback

//Add Func delegate 
dynObj.Func = new Func<int, />                
              ((a, res, str) => Calci(a,res,str));

//Invoke the Func Method
Console.WriteLine("The {0} operation yields {1}", 
				"+", dynObj.Func(12, 4, "+"));

And the Calci Function is here

private static int Calci(int num1, int num2, string op)
{
  int result = 0;
  switch (op)
  {
    case "+":
    result = num1 + num2;
     break;
     case "-":
     result = num1 - num2;
     break;
     case "*":
     result = num1 * num2;
     break;
     case "/":
     result = num1 / num2;
     break;
    }

   return result;
}

This shows how we can use the Func delegate to make simple Arithmetical operations.

Example 4: Notifying Property Change events

As mentioned above , the Expando Object implements the INotifyPropertyChanged interface which is in System.ComponentModel namespace.

That means, whenever we add a new Property to the Expando Object or Change the Value of the existing Property, the PropertyChanged event handler should get trigger. Lets see how it can be done

dynamic dynObject = new ExpandoObject();
 ((INotifyPropertyChanged)dynObject).PropertyChanged += 
 new PropertyChangedEventHandler(Program_PropertyChanged);

dynObject.Property1 = 10;

//Now change the value
dynObject.Property1 = 20;

And the PropertyChanged Event handler is as under

static void Program_PropertyChanged
(
	object sender
	, PropertyChangedEventArgs e
)
{
	Console.WriteLine("Property {0} with value {1}",
					e.PropertyName, ((dynamic)sender).Property1);
}

Here we have simply define a property Property1 and set the initial value to 10. Next we change the property value to 20.The result is

3.jpg

Example 5: Handling events

We can define events to our ExpandoObject.

The steps to follow is listed as under

#region Handling Events
 dynamic dynObjectEvent = new ExpandoObject();
 //Just Adding a memeber
 dynObjectEvent.Value = 10;

 //Step 1: Add a member and set it to null first
 dynObjectEvent.customEventMember = null;
 //Step 2:Now subscribe
 dynObjectEvent.customEventMember += new EventHandler(CustomEventHandler);
 //Step 3: Raise the Event
 EventHandler eh = dynObjectEvent.customEventMember;
 if (eh != null) eh.Invoke(dynObjectEvent, EventArgs.Empty);
//or eh(dynObjectEvent, EventArgs.Empty);

 #endregion

The event handler is defined as under/p>

static void CustomEventHandler(object sender, EventArgs e)
{          
 Console.WriteLine("Custom event handler raised by {0} and has send a value {1}",
                ((dynamic)sender).customEventMember
                , ((dynamic)sender).Value);
}

As can be seen that defining events is a three step prosess.

Step 1: Add a member and set it to null first

dynObjectEvent.customEventMember = null;

Step 2:Now subscribe the event

dynObjectEvent.customEventMember 
	+= new EventHandler(CustomEventHandler);

Step 3: Raise the Event

EventHandler eh = dynObjectEvent.customEventMember;
if (eh != null) eh.Invoke(dynObjectEvent, EventArgs.Empty);

The output being

6.jpg

Conclusion:

In this short tutorial we have seen some of the benifits of Expando Object.

Comments on the topic are highly appreciated for the improvement of the topic.

Thanks for reading the article.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Comments and Discussions

 
GeneralMy vote of 4 Pin
Rudra rafiq17-May-11 0:18
Rudra rafiq17-May-11 0:18 
could have been better...
GeneralMy vote of 1 Pin
Batzen29-Oct-10 7:17
Batzen29-Oct-10 7:17 
GeneralMy vote of 1 Pin
SledgeHammer0127-Oct-10 7:22
SledgeHammer0127-Oct-10 7:22 
General[My vote of 1] Not a great article Pin
BillW3326-Oct-10 6:39
professionalBillW3326-Oct-10 6:39 
GeneralMy vote of 1 Pin
Selvin26-Oct-10 4:55
Selvin26-Oct-10 4:55 
GeneralMy vote of 1 Pin
Sacha Barber25-Oct-10 5:18
Sacha Barber25-Oct-10 5:18 
GeneralMy vote of 1 Pin
Argyle4Ever25-Oct-10 4:14
Argyle4Ever25-Oct-10 4:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.