We can create our own dynamic type by extending the DynamicObject
type.
using System;
using System.Dynamic;
using System.Reflection;
using System.Collections.Generic;
public class MyDynamic: DynamicObject
{
public override bool TryInvokeMember(
InvokeMemberBinder binder, object[] args, out object result)
{
Console.WriteLine(binder.Name + " method was called");
result = null;
return true;
}
}
public class Test
{
static void Main()
{
dynamic d = new MyDynamic();
d.MethodA();
d.MethodB();
}
}
The output:
MethodA method was called
MethodB method was called
DynamicObject
exposes other virtual methods that enable consumers to use other programming constructs as well.
The following correspond to constructs that have representations in C#:
Method | Programming construct |
---|---|
TryInvokeMember | Method |
TryGetMember, TrySetMember | Property or field |
TryGetIndex, TrySetIndex | Indexer |
TryUnaryOperation | Unary operator such as ! |
TryBinaryOperation | Binary operator such as == |
TryConvert | Conversion (cast) to another type |
TryInvoke | Invocation on the object itself e.g., d("foo") |
The following demonstrates TryBinaryOperation
and TryInvoke
:
using System;
using System.Dynamic;
using System.Xml.Linq;
using System.Reflection;
using System.Collections.Generic;
public class Duck : DynamicObject
{
public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result)
{
Console.WriteLine(binder.Operation);
result = "foo";
return true;
}
public override bool TryInvoke(InvokeBinder binder,
object[] args, out object result)
{
Console.WriteLine(args[0]);
result = 123;
return true;
}
}
public class Test
{
static void Main()
{
dynamic d = new Duck();
Console.WriteLine(d + d);
Console.WriteLine(d(78, 'x'));
}
}
The output:
Add
foo
78
123
The following example extends the DynamicObject class to create a wrapper around a dictionary.
Calls to get and set properties on the dynamic type are mapped to the key/value pairs contained in the dictionary:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Dynamic;
class MainClass
{
static void Main(string[] args)
{
dynamic dynamicDict = new MyDynamicDictionary();
// Set some properties.
Console.WriteLine("Setting property values");
dynamicDict.FirstName = "Adam";
dynamicDict.LastName = "Freeman";
// Get some properties.
Console.WriteLine("\nGetting property values");
Console.WriteLine("Firstname {0}", dynamicDict.FirstName);
Console.WriteLine("Lastname {0}", dynamicDict.LastName);
// Call an implemented member.
Console.WriteLine("\nGetting a static property");
Console.WriteLine("Count {0}", dynamicDict.Count);
Console.WriteLine("\nGetting a non-existent property");
try
{
Console.WriteLine("City {0}", dynamicDict.City);
}
catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException e)
{
Console.WriteLine("Caught exception");
}
}
}
class MyDynamicDictionary : DynamicObject
{
private IDictionary<string, object> dict = new Dictionary<string, object>();
public int Count
{
get
{
Console.WriteLine("Get request for Count property");
return dict.Count;
}
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
Console.WriteLine("Get request for {0}", binder.Name);
return dict.TryGetValue(binder.Name, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
Console.WriteLine("Set request for {0}, value {1}", binder.Name, value);
dict[binder.Name] = value;
return true;
}
}
The output:
Setting property values
Set request for FirstName, value Adam
Set request for LastName, value Freeman
Getting property values
Get request for FirstName
Firstname Adam
Get request for LastName
Lastname Freeman
Getting a static property
Get request for Count property
Count 2
Getting a non-existent property
Get request for City
Caught exception
java2s.com | Contact Us | Privacy Policy |
Copyright 2009 - 12 Demo Source and Support. All rights reserved. |
All other trademarks are property of their respective owners. |