如何获得对属性'setter的引用?
本文关键字:setter 引用 何获得 属性 | 更新日期: 2023-09-27 17:50:05
我有一些asp.net代码,填充LINQ to SQL对象(所有字符串字段)的字段与来自张贴表单的值:
userSelections.A = Request.Form["A"];
userSelections.B = Request.Form["B"];
userSelections.C = Request.Form["C"];
userSelections.D = Request.Form["D"];
我想将表单字段的名称和相关的setter对象存储在一个表中,这样我就可以遍历整个集合,而不必编写一堆重复的代码。
是否有一种方法来获得委托到属性setter?例如,假设我有一个类myClass,具有字符串属性myProperty。我可以得到一个委托,像void myPropertySetterDelegate(string val, MyClass this),可以与类的任何实例一起使用吗?
我知道这可以通过反射来完成,但是我的项目中的其他开发人员有性能问题,所以如果可能的话,我更喜欢非反射解决方案。
谢谢!
您可以使用lambda:
Action<MyClass, string> myPropertySetter = (mc, s) => mc.MyProperty = s;
有一个MyClass
的实例:
MyClass something = repo.GetMyClass();
myPropertySetter(something, valueFromSomewhere);
现在,按照你的例子:
Dictionary<string, Action<MyClass, string>> setters = new Dictionary<string, Action<MyClass, string>>();
setters.Add("A", Action<MyClass, string> myPropertySetter = (mc, s) => mc.A = s);
[...]
后:
MyClass something = getFromSomewhere();
foreach (string key in Request.Form.Keys)
{
setters[key](something, Request.Form[key]);
}
您可以使用反射来获取有关您试图绑定到请求的类型的信息,然后生成动态方法(应该缓存它们以重用),以使执行非常快。
public static Action<object, object> CreateSetter(FieldInfo field)
{
DynamicMethod dm = new DynamicMethod("DynamicSet", typeof(void),
new Type[] { typeof(object), typeof(object) }, field.DeclaringType, true);
ILGenerator generator = dm.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldarg_1);
if (field.FieldType.IsValueType)
generator.Emit(OpCodes.Unbox_Any, field.FieldType);
generator.Emit(OpCodes.Stfld, field);
generator.Emit(OpCodes.Ret);
return (Action<object, object>)dm.CreateDelegate(typeof(Action<object, object>));
}
复制这个答案:
Action<int> valueSetter = (Action<int>)Delegate.CreateDelegate(typeof(Action<int>), tc, tc.GetType().GetProperty("Value").GetSetMethod());
是的,这使用反射,但它会产生一个更高性能的委托。此外,"反思"answers"不反思"之间并没有明确的界限。例如,Delegate
类型有很多接受Type
的方法,而Type
类型基本上是由反射组成的。所以使用Delegate
是否使用反射?
Action<string, MyClass> propertySetter = (val, @this) => { @this.Property = val; }
您考虑过扩展方法吗?
http://msdn.microsoft.com/en-us/library/bb311042.aspxhttp://msdn.microsoft.com/en-us/library/bb383977.aspx