C#取代反射取值的方法
来源:互联网 发布:苹果mac如何切换输入法 编辑:程序博客网 时间:2024/04/29 11:26
public class DynamicMethod<T>
{
internal static Func<object, string, object> GetValueDelegate;
internal static Action<object, string, object> SetValueDelegate;
public object GetValue(T instance, string memberName)
{
return GetValueDelegate(instance, memberName);
}
public void SetValue(T instance, string memberName, object newValue)
{
SetValueDelegate(instance, memberName, newValue);
}
public object GetValue(object instance, string memberName)
{
return GetValueDelegate(instance, memberName);
}
public void SetValue(object instance, string memberName, object newValue)
{
SetValueDelegate(instance, memberName, newValue);
}
static DynamicMethod()
{
GetValueDelegate = GenerateGetValue();
SetValueDelegate = GenerateSetValue();
}
private static Func<object, string, object> GenerateGetValue()
{
var type = typeof(T);
var instance = Expression.Parameter(typeof(object), "instance");
var memberName = Expression.Parameter(typeof(string), "memberName");
var nameHash = Expression.Variable(typeof(int), "nameHash");
var calHash = Expression.Assign(nameHash, Expression.Call(memberName, typeof(object).GetMethod("GetHashCode")));
var cases = new List<SwitchCase>();
foreach (var propertyInfo in type.GetProperties())
{
var property = Expression.Property(Expression.Convert(instance, typeof(T)), propertyInfo.Name);
var propertyHash = Expression.Constant(propertyInfo.Name.GetHashCode(), typeof(int));
cases.Add(Expression.SwitchCase(Expression.Convert(property, typeof(object)), propertyHash));
}
var switchEx = Expression.Switch(nameHash, Expression.Constant(null), cases.ToArray());
var methodBody = Expression.Block(typeof(object), new[] { nameHash }, calHash, switchEx);
return Expression.Lambda<Func<object, string, object>>(methodBody, instance, memberName).Compile();
}
private static Action<object, string, object> GenerateSetValue()
{
var type = typeof(T);
var instance = Expression.Parameter(typeof(object), "instance");
var memberName = Expression.Parameter(typeof(string), "memberName");
var newValue = Expression.Parameter(typeof(object), "newValue");
var nameHash = Expression.Variable(typeof(int), "nameHash");
var calHash = Expression.Assign(nameHash, Expression.Call(memberName, typeof(object).GetMethod("GetHashCode")));
var cases = new List<SwitchCase>();
foreach (var propertyInfo in type.GetProperties())
{
if (propertyInfo.CanWrite)
{
var property = Expression.Property(Expression.Convert(instance, typeof(T)), propertyInfo.Name);
var setValue = Expression.Assign(property, Expression.Convert(newValue, propertyInfo.PropertyType));
var propertyHash = Expression.Constant(propertyInfo.Name.GetHashCode(), typeof(int));
cases.Add(Expression.SwitchCase(Expression.Convert(setValue, typeof(object)), propertyHash));
}
}
var switchEx = Expression.Switch(nameHash, Expression.Constant(null), cases.ToArray());
var methodBody = Expression.Block(typeof(object), new[] { nameHash }, calHash, switchEx);
return Expression.Lambda<Action<object, string, object>>(methodBody, instance, memberName, newValue).Compile();
}
{
internal static Func<object, string, object> GetValueDelegate;
internal static Action<object, string, object> SetValueDelegate;
public object GetValue(T instance, string memberName)
{
return GetValueDelegate(instance, memberName);
}
public void SetValue(T instance, string memberName, object newValue)
{
SetValueDelegate(instance, memberName, newValue);
}
public object GetValue(object instance, string memberName)
{
return GetValueDelegate(instance, memberName);
}
public void SetValue(object instance, string memberName, object newValue)
{
SetValueDelegate(instance, memberName, newValue);
}
static DynamicMethod()
{
GetValueDelegate = GenerateGetValue();
SetValueDelegate = GenerateSetValue();
}
private static Func<object, string, object> GenerateGetValue()
{
var type = typeof(T);
var instance = Expression.Parameter(typeof(object), "instance");
var memberName = Expression.Parameter(typeof(string), "memberName");
var nameHash = Expression.Variable(typeof(int), "nameHash");
var calHash = Expression.Assign(nameHash, Expression.Call(memberName, typeof(object).GetMethod("GetHashCode")));
var cases = new List<SwitchCase>();
foreach (var propertyInfo in type.GetProperties())
{
var property = Expression.Property(Expression.Convert(instance, typeof(T)), propertyInfo.Name);
var propertyHash = Expression.Constant(propertyInfo.Name.GetHashCode(), typeof(int));
cases.Add(Expression.SwitchCase(Expression.Convert(property, typeof(object)), propertyHash));
}
var switchEx = Expression.Switch(nameHash, Expression.Constant(null), cases.ToArray());
var methodBody = Expression.Block(typeof(object), new[] { nameHash }, calHash, switchEx);
return Expression.Lambda<Func<object, string, object>>(methodBody, instance, memberName).Compile();
}
private static Action<object, string, object> GenerateSetValue()
{
var type = typeof(T);
var instance = Expression.Parameter(typeof(object), "instance");
var memberName = Expression.Parameter(typeof(string), "memberName");
var newValue = Expression.Parameter(typeof(object), "newValue");
var nameHash = Expression.Variable(typeof(int), "nameHash");
var calHash = Expression.Assign(nameHash, Expression.Call(memberName, typeof(object).GetMethod("GetHashCode")));
var cases = new List<SwitchCase>();
foreach (var propertyInfo in type.GetProperties())
{
if (propertyInfo.CanWrite)
{
var property = Expression.Property(Expression.Convert(instance, typeof(T)), propertyInfo.Name);
var setValue = Expression.Assign(property, Expression.Convert(newValue, propertyInfo.PropertyType));
var propertyHash = Expression.Constant(propertyInfo.Name.GetHashCode(), typeof(int));
cases.Add(Expression.SwitchCase(Expression.Convert(setValue, typeof(object)), propertyHash));
}
}
var switchEx = Expression.Switch(nameHash, Expression.Constant(null), cases.ToArray());
var methodBody = Expression.Block(typeof(object), new[] { nameHash }, calHash, switchEx);
return Expression.Lambda<Action<object, string, object>>(methodBody, instance, memberName, newValue).Compile();
}
}
嗯,记录一下,这个方法可以对实体取代反射取值赋值,不记得哪找到的了
0 0
- C#取代反射取值的方法
- C#各种反射动态赋值取值方法
- C#各种反射动态赋值取值方法
- C#反射取值 源代码
- C#反射的GetCustomAttributes方法
- C#取word中某控件值的方法
- 取代goto语句的方法
- 利用反射获得域的取值
- java通过反射机制取类的属性和方法
- c# 屏幕取词的方法
- c# 屏幕取词的方法
- C# 通过webDAV 取文件的方法
- C#的反射机制调用方法
- C#泛型方法的反射
- C#程序设计(十)----(一个用移位和加法运算取代整数相乘的方法)
- C#反射方法学习
- C++ 取代switch的三种方法
- Android一些过时的(Deprecated)方法取代
- Please change the value of 'Security.salt' in app/config/core.php to a salt value specific to your a
- UVA OJ:458 - The Decoder
- CString和string区别
- ubuntu 12.04中安装svn服务器-亲测总结
- 今天在windows下装了一下ruby on rails 感觉还不错。
- C#取代反射取值的方法
- handler thread
- 轻量级图形报表工具JSCharts (JSChart),内置函数中文参考
- 就这样开始吧
- PJSIP简介配置和PJLIB基础库的使用
- ios之使程序在后台能继续运行
- 第八周(项目一)——实现复数类中的运算符重载(2)。
- Android GridView设置行高,即item高度
- LeetCode (M)