CodePaste Logo
New Snippet New Snippet Recent Snippets Recent Snippets My Snippets My Snippets Web Code Search Snippets Search
Sign inor Register
Language: C#

O Lord! What have I wrought?

190 Views
Copy Code Show/Hide Line Numbers
 
class PrototypeTest
{
    static void Main()
    {
        dynamic pastry1 = new Prototype();
        pastry1.PastryType = "cake";
        pastry1.Cake = new Func<string>(() => "awesome");
 
        Console.WriteLine("Pastry 1's {0} is {1}.", pastry1.PastryType, pastry1.Cake());
 
        dynamic pastry2 = new Prototype(pastry1);
 
        pastry1.Cake = new Func<string>(() => "a lie");
 
        Console.WriteLine("Pastry 1's {0} is {1}.", pastry1.PastryType, pastry1.Cake());
        Console.WriteLine("Pastry 2's {0} is {1}.", pastry2.PastryType, pastry2.Cake());
    }
}
 
public class Prototype : DynamicObject
{
    private readonly IDictionary<string, object> _fields;
 
    public Prototype(Prototype that = null)
    {
        _fields = that == null 
            ? new Dictionary<string, object>()
            : new Dictionary<string, object>(that._fields);
    }
 
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        if (_fields.ContainsKey(binder.Name))
        {
            result = _fields[binder.Name];
            return true;
        }
 
        return base.TryGetMember(binder, out result);
    }
 
    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        if (!_fields.ContainsKey(binder.Name))
            _fields.Add(binder.Name, value);
        else
            _fields[binder.Name] = value;
 
        return true;
    }
 
    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        if (_fields.ContainsKey(binder.Name) && _fields[binder.Name] is Delegate)
        {
            var del = (Delegate)_fields[binder.Name];
            result = del.DynamicInvoke(args);
            return true;
        }
 
        return base.TryInvokeMember(binder, args, out result);
    }
 
    public override bool TryDeleteMember(DeleteMemberBinder binder)
    {
        if (_fields.ContainsKey(binder.Name))
        {
            _fields.Remove(binder.Name);
            return true;
        }
 
        return base.TryDeleteMember(binder);
    }
 
    public override IEnumerable<string> GetDynamicMemberNames()
    {
        return _fields.Keys;
    }
}
by Andy Sherwood
  August 17, 2010 @ 9:22am
Tags:
Description:
The only thing missing from ExpandoObject is the ability to copy and a modify an existing expando object, like JavaScript's prototypes. So I fixed it. Or utterly, utterly destroyed it. I guess it depends on your point of view...

Add a comment


Report Abuse
brought to you by:
West Wind Techologies



If you find this site useful and use it frequently please consider making a donation to support this free service.
Donate