Almost Sorta Real Dynamic in .NET
The new dynamic
keyword is a great way to create and modify a dynamic object in your .NET code - For example, check out this bit of code.
dynamic counter = new { sent = 0, received = 0 }; counter.sent++;
... Oh... wait... That doesn't actually work...
That's because even though you have an object declared as dynamic, it is still just the same old object it always was under the hood. Maybe not the dynamic utopia we were expecting. Seems like plain ol' Reflection with a slightly cleaner syntax.
Bummer...
However, Microsoft was awesome enough to actually allow us to create our own dynamic types by simply inheriting from the DynamicObject
class. This post looks at how we can create a semi-dynamic object by handling the binding methods ourselves.
Our goal is to create an object that we can add, remove and change values on the fly. It ends up being a little easier than we expect. Let's look at the minimum code we are going to need to get started.
public class SimpleDynamic : DynamicObject { //contains the values to use private Dictionary<string, object> _Values = new Dictionary<string, object>(); //handles getting values from our object public override void TryGetMember(GetMemberBinder binder, out object result) { //... } //handles assigning values to our object public override bool TrySetMember(SetMemberBinder binder, object value) { //... } }
In order to create our dynamic object we must handle getting and setting values. We can use a simple Dictionary<string,object>
to hold our values until we need them.
//handles getting values from our object public override void TryGetMember(GetMemberBinder binder, out object result) { return this._Values.TryGetValue(binder.name, out result); } //handles assigning values to our object public override bool TrySetMember(SetMemberBinder binder, object value) { this._Values.Remove(binder.name); if (value is object) { this._Values.Add(binder.name, value); } return true; }
Not much code, but now our dynamic
object is a little more dynamic than it was before. We can now work with properties a lot easier.
//create the new object dynamic simple = new SimpleDynamic(); //add and update some values simple.red = "#f00"; simple.green = "#0f0"; simple.count = 10; simple.add = new Action<int>(value => simple.count += value); //and check the values Console.WriteLine(simple.red); // #f00 Console.WriteLine(simple.green); // #0f0 Console.WriteLine(simple.count); // 10 //invoke methods simple.add(5); Console.WriteLine(simple.count); // 15
Of course this class isn't that helpful since it's only regular Dictionary without string indexes but it is interesting to see how you can make a 'dynamic' object with only a few lines of code.
As for the full source code, it has a few extra features that this class doesn't have.
- Use
Anonymous Types
directly to build out entire objects. - Support for the += operator.
- Enumeration through member names.
- String indexes (for both single and nested properties).
Here are a few examples the Dynamic.cs
class can do.
//create using anonymous types (and nested anonymous types) dynamic info = new Dynamic(new { name = "Hugo", age = 30, settings = new { color = "orange", homepage = "website.com" }}); //add values using += info.create = new { value = false; } info.nested.value.allowed = 55; //enumeration of properties foreach(string prop in info) { Console.WriteLine("{0}: {1}", prop, info[prop]); }
I'd caution against using this a lot in your projects, but it is really interesting to see the kind of control Microsoft has built into the new DynamicObject class.
July 15, 2010
Almost Sorta Real Dynamic in .NET
Post titled "Almost Sorta Real Dynamic in .NET"