Tag Archives: Dynamic

Being Very “Dynamic” – C# 4.0 – I

The world of .NET programming is heading towards a new direction, lots of frameworks, languages, services etc., to choose from. With all the rapid development, C# is also heading towards a new future, being to match the inter-op (or rather co-exist) with its Dynamic siblings (IronPython / IronRuby), it is rather fascinating to bridge the gap between two worlds, where the latter evolved from the previous one.

image

With C# 4.0, we have a new keyword “dynamic”, which offers the following features,

  • Binding with DLR
  • COM – Interop made easy
  • Conversions – between dynamic objects and other types are easy.

There may be scenarios, where constructing a dynamic object is absolutely necessary, Say, if we need to write some object reading from XML or some ATOM feed, we would normally parse the data to some predefined set (a static class). All is good in the world of static typing, and areas where you know exactly how your data (or Business object) would be. For dynamic scenarios, We have dynamic meta-data driven based programming, For instance, we could implement ITypedList, ICustomTypeDescriptor, or any derived version of PropertyDescriptor or any custom interface that defines the logic behind driving the meta-data.

The dynamic introduces a DynamicObject class that acts as an interface between the object store and the interaction between the CLR. You would simply have to inherit from the DynamicObject class and implement methods that would be used on the dynamic instance.

We will check out one simple sample that extends DynamicObject to have an object store,

public class MyDynamicObject : DynamicObject
{
private Dictionary<string, object> members;
public MyDynamicObject()
{
this.members = new Dictionary<string, object>();
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (this.members.ContainsKey(binder.Name))
{
result = this.members[binder.Name];
return true;
}
else
{
return base.TryGetMember(binder, out result);
}
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (!this.members.ContainsKey(binder.Name))
{
this.members.Add(binder.Name, value);
}
else
{
this.members[binder.Name] = value;
}
return true;
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return this.members.Keys;
}
}

To use this we declare a dynamic instance,

dynamic d = new MyDynamicObject();
d.Name = “Hello World”;
Console.WriteLine(“Name : {0}”,d.Name);

With some help from the “reflector”, I was able to get an idea on how the dynamic objects were getting constructed in memory. And, thus came up an idea to write down a helper class that would automatically generate “CallSites” for Get/Set property,

public static class DynamicHelper

{
public static object GetValue(object dyn, string propName)
{
// Warning: this is rather expensive, and should be cached in a real app
var binder = Binder.GetMember(CSharpBinderFlags.None, propName,
dyn.GetType(),
new List<CSharpArgumentInfo> {
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
});
var getterSite = CallSite<Func<CallSite, object, object>>.Create(binder);
return getterSite.Target(getterSite, dyn);
}

public static void SetValue(object dyn, string propName, object value)
{
var binder = Binder.SetMember(CSharpBinderFlags.None, propName, dyn.GetType(), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.LiteralConstant | CSharpArgumentInfoFlags.UseCompileTimeType, null) });
var setterSite = CallSite<Func<CallSite, object, object, object>>.Create(binder);
setterSite.Target.Invoke(setterSite, dyn, value);
}
}

Keeping my fingers crossed, we should probably get the dynamic keyword support for WPF GridDataControl (hopefully with Silverlight too).

Sample codes for the post can be downloaded here.

– Fahad

Advertisements
Tagged