Solved

Expando

Posted on 2016-11-11
4
54 Views
Last Modified: 2016-11-14
I have no practical experience of using Expando having only read about it.  I have a few questions if someone could aid me please?

1. Can I declare an Expando object then make it equal to another object and then add new properties?
2. Can I dynamically add an interface to an Expando object so it can be consumed later as that interface?  A small explanation here,I like to use Interface types in collections, I find it easier to maintain and extend code.
0
Comment
Question by:Alyanto
  • 3
4 Comments
 
LVL 33

Accepted Solution

by:
it_saige earned 500 total points
ID: 41883819
An ExpandoObject is a dynamic object.  The ExpandoObject works by implementing an IDictionary<string, object> (C#) [or IDictionary(Of String, Object) (VB.NET)].

Understanding this, the answer to your first question is yes.

Proof of concept:

In C# -
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Dynamic;

namespace EE_Q28982492
{
	class Program
	{
		static void Main(string[] args)
		{
			Person john = new Person() { ID = 1, FirstName = "John", Birthdate = new DateTime(1984, 02, 16) };
			dynamic clone = john.ToDynamic();
			clone.LastName = "Jones";
			clone.Age = string.Format("{0} year{1}", DateTime.Now.Year - clone.Birthdate.Year, (DateTime.Now.Year - clone.Birthdate.Year) == 1 ? " old" : "s old");

			Console.WriteLine("Properties for John -");
			foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(john.GetType()))
				Console.WriteLine("{{ Name = {0}, Value = {1} }}", property.Name, property.GetValue(john));

			Console.WriteLine("Properties for John's Clone -");
			foreach (KeyValuePair<string, object> pair in (IDictionary<string, object>)clone)
				Console.WriteLine("{{ Name = {0}, Value = {1} }}", pair.Key, pair.Value);

			Console.ReadLine();
		}
	}

	class Person
	{
		public int ID { get; set; }
		public string FirstName { get; set; }
		public DateTime Birthdate { get; set; }
	}

	static class Extensions
	{
		public static dynamic ToDynamic<T>(this T value)
		{
			IDictionary<string, object> expando = new ExpandoObject();
			foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(typeof(T)))
				expando.Add(property.Name, property.GetValue(value));
			return expando as ExpandoObject;
		}
	}
}

Open in new window


In VB.NET -
Imports System.Dynamic
Imports System.ComponentModel

Module Module1
	Sub Main()
		Dim john As New Person() With {.ID = 1, .FirstName = "John", .Birthdate = New DateTime(1984, 2, 16)}
		Dim clone As Object = john.ToDynamic()
		clone.LastName = "Jones"
		clone.Age = String.Format("{0} year{1}", DateTime.Now.Year - clone.Birthdate.Year, If((DateTime.Now.Year - clone.Birthdate.Year) = 1, " old", "s old"))

		Console.WriteLine("Properties for John -")
		For Each [property] As PropertyDescriptor In TypeDescriptor.GetProperties(john.[GetType]())
			Console.WriteLine("{{ Name = {0}, Value = {1} }}", [property].Name, [property].GetValue(john))
		Next

		Console.WriteLine("Properties for John's Clone -")
		For Each pair As KeyValuePair(Of String, Object) In DirectCast(clone, IDictionary(Of String, Object))
			Console.WriteLine("{{ Name = {0}, Value = {1} }}", pair.Key, pair.Value)
		Next

		Console.ReadLine()
	End Sub
End Module

Class Person
	Public Property ID() As Integer
	Public Property FirstName() As String
	Public Property Birthdate() As DateTime
End Class

Module Extensions
	<System.Runtime.CompilerServices.Extension()> _
	Public Function ToDynamic(Of T)(value As T) As ExpandoObject
		Dim expando As IDictionary(Of String, Object) = New ExpandoObject()
		For Each [property] As PropertyDescriptor In TypeDescriptor.GetProperties(GetType(T))
			expando.Add([property].Name, [property].GetValue(value))
		Next
		Return TryCast(expando, ExpandoObject)
	End Function
End Module

Open in new window


Each of which produce the following output -Capture.JPG
The very nature of the expando object makes your second question irrelevant because it can be anything.  If you are going to use an interface, this requires static typing which is counter-intuitive to the expando object which is dynamic.

-saige-
2
 
LVL 1

Author Comment

by:Alyanto
ID: 41883836
Hi it_saige
In the mean time I had arrived at about the point you demonstrate here.  What I am working on is mediator pattern in WPF.  The problem is to do with control collision so I am working with UIElements.  I was thinking rather than write a new class, translate the information from the various child UIElements on the panel into a collection of this new class I could use ExpandoObject to inherit the current child add new properties and implement and interface and an abstract class.

so for me this is the abstract subscriber and an interface called ISubscriptionMembership (add and remove subscription)

I am doing some feasibility of doing this which is where this question comes from, best to not count my chickens before they hatch.

/Aly
0
 
LVL 1

Author Comment

by:Alyanto
ID: 41883959
Added a follow on question, please take a look.
0
 
LVL 1

Author Closing Comment

by:Alyanto
ID: 41886065
On the button, many thanks.
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

829 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question