Jea*_*nal 8 .net dynamic-language-runtime
我想在利用DLR绑定机制的同时访问对象上的属性.
dynamicC#中的关键字),因为我在编译时不知道属性名称;IDictionary<string, object>我所知,转换为只解决了选择实现该接口的动态类的情况(例如ExpandoObject).这是演示代码:
static void Main(string[] args)
{
dynamic obj = new System.Dynamic.ExpandoObject();
obj.Prop = "Value";
// C# dynamic binding.
Console.Out.WriteLine(obj.Prop);
// IDictionary<string, object>
Console.Out.WriteLine((obj as IDictionary<string, object>)["Prop"]);
// Attempt to use reflection.
PropertyInfo prop = obj.GetType().GetProperty("Prop");
Console.Out.WriteLine(prop.GetValue(obj, new object[] { }));
Console.In.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
我终于可以通过使用C#运行时绑定器来完成它.(我相信应该可以通过更简单的绑定器实现来实现这一点,但我无法编写一个工作的 - 可能编写一个"简单"的实现已经非常困难了).
using Microsoft.CSharp.RuntimeBinder;
private class TestClass
{
public String Prop { get; set; }
}
private static Func<object, object> BuildDynamicGetter(Type targetType, String propertyName)
{
var rootParam = Expression.Parameter(typeof(object));
var propBinder = Microsoft.CSharp.RuntimeBinder.Binder.GetMember(CSharpBinderFlags.None, propertyName, targetType, new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
DynamicExpression propGetExpression = Expression.Dynamic(propBinder, typeof(object),
Expression.Convert(rootParam, targetType));
Expression<Func<object, object>> getPropExpression = Expression.Lambda<Func<object, object>>(propGetExpression, rootParam);
return getPropExpression.Compile();
}
static void Main(string[] args)
{
dynamic root = new TestClass { Prop = "StatValue" };
Console.Out.WriteLine(root.Prop);
var dynGetter = BuildDynamicGetter(root.GetType(), "Prop");
Console.Out.WriteLine(dynGetter(root));
root = new System.Dynamic.ExpandoObject();
root.Prop = "ExpandoValue";
Console.WriteLine(BuildDynamicGetter(root.GetType(), "Prop").Invoke(root));
Console.Out.WriteLine(root.Prop);
Console.In.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
输出:
StatValue
StatValue
ExpandoValue
ExpandoValue
Run Code Online (Sandbox Code Playgroud)