In this post, I will show how to create your own dynamic object in c# 4.0. Create a class and Inherit it from DyanicObject (Provides a base class for specifying dynamic behaviour at run time. This class must be inherited from; you cannot instantiate it directly). It has the following virtual method that you must override to add dynamic behaviour to your class.
// Summary:
// Returns the enumeration of all dynamic member names.
//
// Returns:
// The list of dynamic member names.
public virtual IEnumerable<string> GetDynamicMemberNames();
//
// Summary:
// The provided MetaObject will dispatch to the Dynamic virtual methods. The
// object can be encapsulated inside of another MetaObject to provide custom
// behavior for individual actions.
//
// Parameters:
// parameter:
// The expression representing the MetaObject to dispatch to the Dynamic virtual
// methods.
//
// Returns:
// The object of the System.Dynamic.DynamicMetaObject type.
public virtual DynamicMetaObject GetMetaObject(Expression parameter);
//
// Summary:
// Provides the implementation of performing a binary operation.
//
// Parameters:
// binder:
// The binder provided by the call site.
//
// arg:
// The right operand for the operation.
//
// result:
// The result of the operation.
//
// Returns:
// Returns true if the operation is complete, false if the call site should
// determine behavior.
public virtual bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result);
//
// Summary:
// Provides the implementation of converting the DynamicObject to another type.
//
// Parameters:
// binder:
// The binder provided by the call site.
//
// result:
// The result of the conversion.
//
// Returns:
// Returns true if the operation is complete, false if the call site should
// determine behavior.
public virtual bool TryConvert(ConvertBinder binder, out object result);
//
// Summary:
// Provides the implementation of creating an instance of the DynamicObject.
//
// Parameters:
// binder:
// The binder provided by the call site.
//
// args:
// The arguments used for creation.
//
// result:
// The created instance.
//
// Returns:
// Returns true if the operation is complete, false if the call site should
// determine behavior.
public virtual bool TryCreateInstance(CreateInstanceBinder binder, object[] args, out object result);
//
// Summary:
// Provides the implementation of performing a delete index operation.
//
// Parameters:
// binder:
// The binder provided by the call site.
//
// indexes:
// The indexes to be deleted.
//
// Returns:
// Returns true if the operation is complete, false if the call site should
// determine behavior.
public virtual bool TryDeleteIndex(DeleteIndexBinder binder, object[] indexes);
//
// Summary:
// Provides the implementation of deleting a member.
//
// Parameters:
// binder:
// The binder provided by the call site.
//
// Returns:
// Returns true if the operation is complete, false if the call site should
// determine behavior.
public virtual bool TryDeleteMember(DeleteMemberBinder binder);
//
// Summary:
// Provides the implementation of performing a get index operation.
//
// Parameters:
// binder:
// The binder provided by the call site.
//
// indexes:
// The indexes that will be used in the operation.
//
// result:
// The result of the operation.
//
// Returns:
// Returns true if the operation is complete, false if the call site should
// determine behavior.
public virtual bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result);
//
// Summary:
// Provides the implementation of getting a member.
//
// Parameters:
// binder:
// The binder provided by the call site.
//
// result:
// The result of the get operation.
//
// Returns:
// Returns true if the operation is complete, false if the call site should
// determine behavior.
public virtual bool TryGetMember(GetMemberBinder binder, out object result);
//
// Summary:
// Provides the implementation of invoking the DynamicObject.
//
// Parameters:
// binder:
// The binder provided by the call site.
//
// args:
// The arguments that will be used for the invocation.
//
// result:
// The result of the invocation.
//
// Returns:
// Returns true if the operation is complete, false if the call site should
// determine behavior.
public virtual bool TryInvoke(InvokeBinder binder, object[] args, out object result);
//
// Summary:
// Provides the implementation of calling a member.
//
// Parameters:
// binder:
// The binder provided by the call site.
//
// args:
// The arguments that will be used for the invocation.
//
// result:
// The result of the invocation.
//
// Returns:
// Returns true if the operation is complete, false if the call site should
// determine behavior.
public virtual bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result);
//
// Summary:
// Provides the implementation of performing a set index operation.
//
// Parameters:
// binder:
// The binder provided by the call site.
//
// indexes:
// The indexes that will be used in the operation.
//
// value:
// The value to set.
//
// Returns:
// Returns true if the operation is complete, false if the call site should
// determine behavior.
public virtual bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value);
//
// Summary:
// Provides the implementation of setting a member.
//
// Parameters:
// binder:
// The binder provided by the call site.
//
// value:
// The value to set.
//
// Returns:
// Returns true if the operation is complete, false if the call site should
// determine behavior.
public virtual bool TrySetMember(SetMemberBinder binder, object value);
//
// Summary:
// Provides the implementation of performing a unary operation.
//
// Parameters:
// binder:
// The binder provided by the call site.
//
// result:
// The result of the operation.
//
// Returns:
// Returns true if the operation is complete, false if the call site should
// determine behavior.
public virtual bool TryUnaryOperation(UnaryOperationBinder binder, out object result);
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Dynamic;
namespace CustomDyamicObject
{
class Program
{
static void Main(string[] args)
{ //Custom Dynamic Object
dynamic bag = new Bag();
bag.Name = "Hello C#";
bag.Age = 12;
Console.WriteLine("{0}-{1}", bag.Name, bag.Age);
Action<dynamic> hi = (self) => Console.WriteLine("Hello from {0}", self.Name);
bag.SayHi = hi;
bag.SayHi();
Console.ReadLine();
}
}
public class Bag : DynamicObject
{
Dictionary<string, object> _data = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = _data[binder.Name];
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
_data[binder.Name] = value;
return true;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
dynamic target = _data[binder.Name];
int length = args.Length;
if (length == 0)
{
target(this);
result = true;
return true;
}
else if (length == 1)
{
target(this, args[1]);
result = true;
return true;
}
else
{
throw new NotImplementedException();
}
}
}
}