using System;
using System.Collections.Generic;
using System.Dynamic;
public class MyExpandoObject : DynamicObject
{
private Dictionary<string, object> _dict = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = null;
if (_dict.ContainsKey(binder.Name.ToUpper()))
{
result = _dict[binder.Name.ToUpper()];
return true;
}
return false;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (_dict.ContainsKey(binder.Name.ToUpper()))
_dict[binder.Name.ToUpper()] = value;
else
_dict.Add(binder.Name.ToUpper(), value);
return true;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
result = new Action(() => { });
if (_dict.ContainsKey(binder.Name.ToUpper()))
{
Type dictType = _dict.GetType();
try
{
result = dictType.InvokeMember(
binder.Name,
System.Reflection.BindingFlags.InvokeMethod,
null,
this,
args
);
return true;
}
catch
{
return false;
}
}
return false;
}
//public static void aa(string str)
public void aa(string str)
{
Console.WriteLine("input {0}", str);
}
//public static void bb()
public void bb()
{
Console.WriteLine("i loving coding!!!");
}
public static void ComeFrom(string country)
{
Console.WriteLine("I'm from {0}", country);
}
}
class TestMyExpandoObject
{
class gg : DynamicObject
{
public static void TestComeFrom(string country)
{
Console.WriteLine("I'm from {0}", country);
}
Dictionary<string, object> dictionary = new Dictionary<string, object>();
public override bool TrySetMember(SetMemberBinder binder, object value)
{
dictionary[binder.Name] = value;
return true;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return dictionary.TryGetValue(binder.Name, out result);
}
}
static void Main()
{
dynamic t = new gg();
t.fn = new Action<string>(s => gg.TestComeFrom(s));
t.fn("t");
Console.WriteLine("========================================");
dynamic vessel = new MyExpandoObject();
vessel.Name = "Little Miss Understood";
vessel.Age = 12;
vessel.KeelLengthInFeet = 32;
vessel.Longitude = 37.55f;
vessel.Latitude = -76.34f;
//vessel.aa("China");
//vessel.bb();
//Console.WriteLine("========================================");
vessel.fn = new Action<string>(s => MyExpandoObject.ComeFrom(s));
vessel.fn("t");
Console.WriteLine("========================================");
//vessel.fb = new Action(MyExpandoObject.bb);
Console.WriteLine("The {0} year old vessel " +
"named {1} has a keel length of {2} feet " +
"and is currently located at {3} / {4}.",
vessel.AGE, vessel.name,
vessel.keelLengthINfeet,
vessel.Longitude, vessel.Latitude);
Console.ReadLine();
}
}
实际的时候,建议用ConcurrentDictionary替换Dictionary,eg:
class Person : System.Dynamic.DynamicObject
{
//Dictionary<string, object> properties = new Dictionary<string, object>();
ConcurrentDictionary<string, object> properties = new ConcurrentDictionary<string, object>();
public override bool TryGetMember(System.Dynamic.GetMemberBinder binder, out object result)
{
return properties.TryGetValue(binder.Name, out result);
}
public override bool TrySetMember(System.Dynamic.SetMemberBinder binder, object value)
{
properties[binder.Name] = value;
return true;
}
public ConcurrentDictionary<string, object> GetProperties()
{
return properties;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("--- Person attributes ---");
foreach (var key in properties.Keys)
{
//We use the chaining property of the StringBuilder methods
sb.Append(key).Append(": ").AppendLine(properties[key].ToString());
}
return sb.ToString();
}
}
static void Main(string[] args)
{
dynamic person = new Person();
person.Name = "Florian";
person.Age = 28;
Console.WriteLine(person);
person.Country = "Germany";
Console.WriteLine(person);
Console.ReadKey();
}