Improve company productivity with a Business Account.Sign Up

x
?
Solved

Expando

Posted on 2016-11-11
4
Medium Priority
?
98 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 36

Accepted Solution

by:
it_saige earned 2000 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

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

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!
Native ability to set a user account password via AD GPO was removed because the passwords can be easily decrypted by any authenticated user in the domain. Microsoft recommends LAPS as a replacement and I have written an article that does something …
Hi, this video explains a free download that you can incorporate into your Access databases, or use stand-alone for contact management. Contacts -- Names, Addresses, Phone Numbers, eMail Addresses, Websites, Lists, Projects, Notes, Attachments…
Watch the video of Kernel Migrator for SharePoint, which demonstrate the process easily of migration from SharePoint to SharePoint, OneDrive for Business & Google Drive servers, Public Folder to SharePoint, File Server to SharePoint. The tool has va…

606 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