如何获得对属性'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),可以与类的任何实例一起使用吗?

我知道这可以通过反射来完成,但是我的项目中的其他开发人员有性能问题,所以如果可能的话,我更喜欢非反射解决方案。

谢谢!

如何获得对属性'setter的引用?

您可以使用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