public class FastProperty<T>
    {
        public delegate void SetValueDelegateHandler(T owner, object value);
        private readonly Type ParameterType = typeof(object);        private T _owner;
        public T Owner { get { return this._owner; } }        private Type _ownerType;        public FastProperty(T owner)
        {
            this._owner = owner;
            this._ownerType = typeof(T);
        }
        public SetValueDelegateHandler SetPropertyValue(string propertyName, object value)
        {            // 指定函数名
            string methodName = "set_" + propertyName;
            // 搜索函数,不区分大小写 IgnoreCase
            var callMethod = this._ownerType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic);
            // 获取参数
            var para = callMethod.GetParameters()[0];
            // 创建动态函数
            DynamicMethod method = new DynamicMethod("EmitCallable", null, new Type[] { this._ownerType, ParameterType }, this._ownerType.Module);
            // 获取动态函数的 IL 生成器
            var il = method.GetILGenerator();
            // 创建一个本地变量,主要用于 Object Type to Propety Type
            var local = il.DeclareLocal(para.ParameterType, true);
            // 加载第 2 个参数【(T owner, object value)】的 value
            il.Emit(OpCodes.Ldarg_1);
            if (para.ParameterType.IsValueType)
            {
                il.Emit(OpCodes.Unbox_Any, para.ParameterType);// 如果是值类型,拆箱 string = (string)object;
            }
            else
            {
                il.Emit(OpCodes.Castclass, para.ParameterType);// 如果是引用类型,转换 Class = object as Class
            }
            il.Emit(OpCodes.Stloc, local);// 将上面的拆箱或转换,赋值到本地变量,现在这个本地变量是一个与目标函数相同数据类型的字段了。
            il.Emit(OpCodes.Ldarg_0);   // 加载第一个参数 owner
            il.Emit(OpCodes.Ldloc, local);// 加载本地参数
            il.EmitCall(OpCodes.Callvirt, callMethod, null);//调用函数
            il.Emit(OpCodes.Ret);   // 返回
            /* 生成的动态函数类似:
             * void EmitCallable(T owner, object value)
             * {
             *     T local = (T)value;
             *     owner.Method(local);
             * }
             */
            return method.CreateDelegate(typeof(SetValueDelegateHandler)) as SetValueDelegateHandler;
        }
    }详情:http://www.cnblogs.com/mrlen/archive/2010/06/10/1755357.html
这个方法可以访问非私有的函数或属性。
可是对于私有属性就无能为力了。我这里有 3.5 才有 LINQ 方式。可是我希望是基于 2.0 实现的。不知道上面有哪个地方需要“改”?好久没有发200分的帖子了……可用分一直很少。都不敢发问。囧~~~~

解决方案 »

  1.   

    get set 访问器 就是 用来访问和负值的啊
      

  2.   


    不是我是希望这么赋值:我有一个 object 实例,我不知道它的类型。
    public void SetValue(object target,string propertyName,object value)
    {
         动态调用 t = new 动态调用(target);
         t.SetValue(propertyName,value);
    }
      

  3.   

    性能太耗。3.5的 linq反射 不错。但是我希望基于 2.0。
    听说“Emit”什么都可以。所以我就想问问方法。
      

  4.   

    C#反射调用另外一个类中的私有字段和方法:http://blog.csdn.net/wojiaosha123/archive/2010/02/05/5290549.aspx
      

  5.   

    假设需要动态调用的类型是:public class User
    {
         public string Username { get; private set;}
    }
      

  6.   

    http://msdn.microsoft.com/zh-cn/library/system.reflection.emit.propertybuilder(VS.95).aspx
      

  7.   

    没那么麻烦了。static void Main(string[] args)
    {
        TestClass obj = new TestClass();
        FastProperty<TestClass> fp = new FastProperty<TestClass>(obj);
        fp.SetPropertyValue2("Value", 5000);
        Console.ReadKey();
    }public static void SetPropertyValue2(object Owner, string propertyName, object value)
    {
        PropertyInfo[] pis = Owner.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance);
        foreach (PropertyInfo pi in pis)
        {
            if (pi.Name == propertyName)
            {
                pi.SetValue(Owner, value, null);
            }
        }
    }public class TestClass
    {
        private int _value = 500;
        private int Value
        {
            get
            {
                return _value;
            }
            set
            {
                _value = value;
                Console.WriteLine("Value changed! New value is " + value.ToString());
            }
        }
    }
      

  8.   

    贴错例子了
    static void Main(string[] args)
    {
        //声明自定义类型,实例化
        TestClass obj = new TestClass();
        //调用静态方法设置值
        SetNonePublicPropertyValue(obj, "Value", 5000);
        Console.ReadKey();
    }/// <summary>
    /// 设置Protected/Private类型的属性值
    /// </summary>
    /// <param name="Owner">要设置的对象</param>
    /// <param name="propertyName">属性名</param>
    /// <param name="value">值</param>
    public static void SetNonePublicPropertyValue(object Owner, string propertyName, object value)
    {
        //获取非公开的成员属性
        PropertyInfo pi = Owner.GetType().GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance);
        if (pi != null)//如果获取到了,说明你调用没错
        {
            pi.SetValue(Owner, value, null);//设置值,这个最后一个属性,是索引值,如果属性本身是Array或List,这里要写索引编号或索引器要求的值。
        }
    }
      

  9.   

    仔细看完了。他这样可以调用非公开方法么?非公开的是要反射调用invoke的哦。
    上次那个方法不可以么?
      

  10.   


    可以的。上次的方法是完全可以的。但是 Linq 是在 3.5 实现的。2.0是无法实现的。
      

  11.   

    刚测试了一下,他这样做并不会很快。效率也不高。
    测试例子: using System;
    using System.Linq;
    using System.Reflection;
    using System.Reflection.Emit;namespace CSharpConsole06
    {
        class Program
        {
            static void Main(string[] args)
            {
                //声明自定义类型,实例化
                TestClass obj = new TestClass();
                //调用静态方法设置值
                FastProperty<TestClass> fp = new FastProperty<TestClass>(obj);
                FastPropertyBufferd<TestClass> fp2 = new FastPropertyBufferd<TestClass>(obj, "Value");
                int tick = Environment.TickCount;
                for (int i = 0; i < 100000; i++)
                {
                    fp.SetPropertyValue("Value", 5000).Invoke(obj, 5000);   
                }
                tick = Environment.TickCount - tick;
                Console.WriteLine("FastProperty".PadRight(20) + " : " + tick.ToString());
                tick = Environment.TickCount;
                for (int i = 0; i < 100000; i++)
                {
                    fp2.SetValue(5000);
                }
                tick = Environment.TickCount - tick;
                Console.WriteLine("FastPropertyBufferd".PadRight(20) + " : " + tick);
                tick = Environment.TickCount;
                for (int i = 0; i < 100000; i++)
                {
                    SetNonePublicPropertyValue(obj, "Value", 5000);
                }
                tick = Environment.TickCount - tick;
                Console.WriteLine("Direct reflect".PadRight(20) + " : " + tick);
                Console.ReadKey();
            }        public class TestClass
            {
                private int _value = 500;
                public int Value
                {
                    get
                    {
                        return _value;
                    }
                    set
                    {
                        _value = value;
                        //Console.WriteLine("Value changed! New value is " + value.ToString());
                    }
                }
            }        /// <summary>
            /// 设置Protected/Private类型的属性值
            /// </summary>
            /// <param name="Owner">要设置的对象</param>
            /// <param name="propertyName">属性名</param>
            /// <param name="value">值</param>
            public static void SetNonePublicPropertyValue(object Owner, string propertyName, object value)
            {
                Owner.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance).ToList().ForEach(p => Console.WriteLine(p.Name));
                //获取非公开的成员属性
                PropertyInfo pi = Owner.GetType().GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Default);
                if (pi != null)//如果获取到了,说明你调用没错
                {
                    pi.SetValue(Owner, value, null);//设置值,这个最后一个属性,是索引值,如果属性本身是Array或List,这里要写索引编号或索引器要求的值。
                }
            }        /// <summary>
            /// 缓存反射结果的类,提高访问速度
            /// </summary>
            /// <typeparam name="T">类型</typeparam>
            public class FastPropertyBufferd<T>
            {
                private T _owner = default(T);
                MethodInfo mi = null;
                public FastPropertyBufferd(T owner,string propertyName)
                {
                    _owner = owner;
                    mi = typeof(T).GetMethod("set_" + propertyName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic);
                }
                public void SetValue(object value)
                {
                    mi.Invoke(_owner, new object[] { value });
                }
            }        public class FastProperty<T>
            {
                public delegate void SetValueDelegateHandler(T owner, object value);
                private readonly Type ParameterType = typeof(object);            private T _owner;
                public T Owner { get { return this._owner; } }            private Type _ownerType;            public FastProperty(T owner)
                {
                    this._owner = owner;
                    this._ownerType = typeof(T);
                }            public void SetPropertyValue2(string propertyName, object value)
                {
                    PropertyInfo[] pis = Owner.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance);
                    foreach (PropertyInfo pi in pis)
                    {
                        if (pi.Name == propertyName)
                        {
                            pi.SetValue(Owner, value, null);
                        }
                    }
                }            public SetValueDelegateHandler SetPropertyValue(string propertyName, object value)
                {
                    // 指定函数名
                    string methodName = "set_" + propertyName;
                    // 搜索函数,不区分大小写 IgnoreCase
                    var callMethod = this._ownerType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic);
                    // 获取参数
                    var para = callMethod.GetParameters()[0];
                    // 创建动态函数
                    DynamicMethod method = new DynamicMethod("EmitCallable", null, new Type[] { this._ownerType, ParameterType }, this._ownerType.Module);
                    // 获取动态函数的 IL 生成器
                    var il = method.GetILGenerator();
                    // 创建一个本地变量,主要用于 Object Type to Propety Type
                    var local = il.DeclareLocal(para.ParameterType, true);
                    // 加载第 2 个参数【(T owner, object value)】的 value
                    il.Emit(OpCodes.Ldarg_1);
                    if (para.ParameterType.IsValueType)
                    {
                        il.Emit(OpCodes.Unbox_Any, para.ParameterType);// 如果是值类型,拆箱 string = (string)object;
                    }
                    else
                    {
                        il.Emit(OpCodes.Castclass, para.ParameterType);// 如果是引用类型,转换 Class = object as Class
                    }
                    il.Emit(OpCodes.Stloc, local);// 将上面的拆箱或转换,赋值到本地变量,现在这个本地变量是一个与目标函数相同数据类型的字段了。
                    il.Emit(OpCodes.Ldarg_0);   // 加载第一个参数 owner
                    il.Emit(OpCodes.Ldloc, local);// 加载本地参数
                    il.EmitCall(OpCodes.Callvirt, callMethod, null);//调用函数
                    il.Emit(OpCodes.Ret);   // 返回
                    /* 生成的动态函数类似:
                     * void EmitCallable(T owner, object value)
                     * {
                     *     T local = (T)value;
                     *     owner.Method(local);
                     * }
                     */
                    return method.CreateDelegate(typeof(SetValueDelegateHandler)) as SetValueDelegateHandler;
                }
            }
        }
    }测试结果:FastProperty         : 14618
    FastPropertyBufferd  : 187
    Direct reflect       : 172
      

  12.   

    这个测试可能不太公正:FastProperty<TestClass>.SetValueDelegateHandler setter = fp.SetPropertyValue("Value", 5000);  //<---改动
    for (int i = 0; i < 100000; i++)
    {
        setter(obj, 5000);
    }我的结果:
    FastProperty         : 15
    FastPropertyBufferd  : 531
    Direct reflect       : 218
      

  13.   

    不需要emit,直接用反射+委托做,性能不比emit差:class T { private object P { get; set; } }//得到私有属性
    System.Reflection.PropertyInfo p = typeof(T).GetProperty("P", ystem.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);//创建get,set委托
    T t = new T();
    Func<object> PGet = Delegate.CreateDelegate(typeof(Func<object>), t, p.GetGetMethod(true)) as Func<object>;
    Action<object> PSet = Delegate.CreateDelegate(typeof(Action<object>), t, p.GetSetMethod(true)) as Action<object>;//访问属性
    PSet(new object());
    object o = PGet();
      

  14.   

    多谢gomoku和guoyichao的指点。
    如gomoku所说,那样测试的确有点不合适。
    多谢guoyichao的提醒,这样的确很快。
    重新修改了测试例子:using System;
    using System.Reflection;
    using System.Reflection.Emit;class Program
    {
        static void Main(string[] args)
        {
            //声明自定义类型,实例化
            TestClass obj = new TestClass();
            //调用静态方法设置值
            FastProperty<TestClass> fp = new FastProperty<TestClass>(obj);
            FastPropertyBufferd<TestClass> fp2 = new FastPropertyBufferd<TestClass>(obj, "Value");
            int tick = Environment.TickCount;
            FastProperty<TestClass>.SetValueDelegateHandler setter = fp.SetPropertyValue("Value", 5000);
            for (int i = 0; i < 1000000; i++)
            {
                setter.Invoke(obj, 5000);
            }
            tick = Environment.TickCount - tick;
            Console.WriteLine("FastProperty".PadRight(20) + " : " + tick.ToString());
            tick = Environment.TickCount;
            for (int i = 0; i < 1000000; i++)
            {
                fp2.SetValue(5000);
            }
            tick = Environment.TickCount - tick;
            Console.WriteLine("FastPropertyBufferd".PadRight(20) + " : " + tick);
            tick = Environment.TickCount;
            for (int i = 0; i < 1000000; i++)
            {
                SetNonePublicPropertyValue(obj, "Value", 5000);
            }
            tick = Environment.TickCount - tick;
            Console.WriteLine("Direct reflect".PadRight(20) + " : " + tick);
            tick = Environment.TickCount;
            SetValueHandler del = Delegate.CreateDelegate(typeof(SetValueHandler),obj, "set_Value") as SetValueHandler;
            for (int i = 0; i < 1000000; i++)
            {
                del(5000);
            }
            tick = Environment.TickCount - tick;
            Console.WriteLine("CreateDelegate reflect".PadRight(20) + " : " + tick);
            Console.ReadKey();
        }    delegate void SetValueHandler(Int32 value);    public class TestClass
        {
            private int _value = 500;
            public int Value
            {
                get
                {
                    return _value;
                }
                set
                {
                    _value = value;
                    //Console.WriteLine("Value changed! New value is " + value.ToString());
                }
            }
        }    /// <summary>
        /// 设置Protected/Private类型的属性值
        /// </summary>
        /// <param name="Owner">要设置的对象</param>
        /// <param name="propertyName">属性名</param>
        /// <param name="value">值</param>
        public static void SetNonePublicPropertyValue(object Owner, string propertyName, object value)
        {
            //Owner.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance).ToList().ForEach(p => Console.WriteLine(p.Name));
            //获取非公开的成员属性
            PropertyInfo pi = Owner.GetType().GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Default);
            if (pi != null)//如果获取到了,说明你调用没错
            {
                pi.SetValue(Owner, value, null);//设置值,这个最后一个属性,是索引值,如果属性本身是Array或List,这里要写索引编号或索引器要求的值。
            }
        }    /// <summary>
        /// 缓存反射结果的类,提高访问速度
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        public class FastPropertyBufferd<T>
        {
            private T _owner = default(T);
            MethodInfo mi = null;
            public FastPropertyBufferd(T owner, string propertyName)
            {
                _owner = owner;
                mi = typeof(T).GetMethod("set_" + propertyName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic);
            }
            public void SetValue(object value)
            {
                mi.Invoke(_owner, new object[] { value });
            }
        }    public class FastProperty<T>
        {
            public delegate void SetValueDelegateHandler(T owner, object value);
            private readonly Type ParameterType = typeof(object);        private T _owner;
            public T Owner { get { return this._owner; } }        private Type _ownerType;        public FastProperty(T owner)
            {
                this._owner = owner;
                this._ownerType = typeof(T);
            }        public void SetPropertyValue2(string propertyName, object value)
            {
                PropertyInfo[] pis = Owner.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance);
                foreach (PropertyInfo pi in pis)
                {
                    if (pi.Name == propertyName)
                    {
                        pi.SetValue(Owner, value, null);
                    }
                }
            }        public SetValueDelegateHandler SetPropertyValue(string propertyName, object value)
            {
                // 指定函数名
                string methodName = "set_" + propertyName;
                // 搜索函数,不区分大小写 IgnoreCase
                MethodInfo callMethod = this._ownerType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic);
                // 获取参数
                ParameterInfo para = callMethod.GetParameters()[0];
                // 创建动态函数
                DynamicMethod method = new DynamicMethod("EmitCallable", null, new Type[] { this._ownerType, ParameterType }, this._ownerType.Module);
                // 获取动态函数的 IL 生成器
                ILGenerator il = method.GetILGenerator();
                // 创建一个本地变量,主要用于 Object Type to Propety Type
                LocalBuilder local = il.DeclareLocal(para.ParameterType, true);
                // 加载第 2 个参数【(T owner, object value)】的 value
                il.Emit(OpCodes.Ldarg_1);
                if (para.ParameterType.IsValueType)
                {
                    il.Emit(OpCodes.Unbox_Any, para.ParameterType);// 如果是值类型,拆箱 string = (string)object;
                }
                else
                {
                    il.Emit(OpCodes.Castclass, para.ParameterType);// 如果是引用类型,转换 Class = object as Class
                }
                il.Emit(OpCodes.Stloc, local);// 将上面的拆箱或转换,赋值到本地变量,现在这个本地变量是一个与目标函数相同数据类型的字段了。
                il.Emit(OpCodes.Ldarg_0);   // 加载第一个参数 owner
                il.Emit(OpCodes.Ldloc, local);// 加载本地参数
                il.EmitCall(OpCodes.Callvirt, callMethod, null);//调用函数
                il.Emit(OpCodes.Ret);   // 返回
                /* 生成的动态函数类似:
                 * void EmitCallable(T owner, object value)
                 * {
                 *     T local = (T)value;
                 *     owner.Method(local);
                 * }
                 */
                return method.CreateDelegate(typeof(SetValueDelegateHandler)) as SetValueDelegateHandler;
            }
        }
    }
    结果:FastProperty           : 47
    FastPropertyBufferd    : 4618
    Direct reflect         : 452
    CreateDelegate reflect : 16
      

  15.   

    // 创建动态函数
    DynamicMethod method = new DynamicMethod("EmitCallable", null, new Type[] { this._ownerType, ParameterType }, this._ownerType.Module, true);
    加上的true意味着跳过检查(skipVisibility),然后私有/非私有就都可以访问了。另:23楼guoyichao的方法有个局限,Func<object>不能推广到Func<T>的情况,除非显式指定属性的类型T。
      
      

  16.   

    小弟有个疑问,如果仅有一个未知类型的对象实例,如何用FastProperty对它的某个属性(知道属性名,不知道类型)进行赋值呢?
    各位大大帮帮忙,小弟困绕很久了。
      

  17.   

    比如我有以下这个函数,如何改成FastProperty来实现赋值和取值呢?        private void SetProperty(object obj, string propertyName, object value)
            {
                Type type = obj.GetType();
                PropertyInfo p = type.GetProperty(propertyName);
                p.SetValue(obj, value, null);
            }
      

  18.   

    比如我有以下这个函数,如何改成FastProperty来实现赋值和取值呢? private void SetProperty(object obj, string propertyName, object value)
      {
        Type type = obj.GetType();
        PropertyInfo p = type.GetProperty(propertyName);
        p.SetValue(obj, value, null);
      }
      

  19.   

    额。什么时候被推荐了。
    后来我又有更好的办法了。如果只是针对 ORM,特别注重效率的话,还是需要 switch + Delegate.CreateDelegate,虽然目前框架中没有使用这个策略,但是我相信这个方式使得 ORM 的性能损耗降到最低!
      

  20.   

    如果是属性的话,可以用FastInvoke,效率足够满足要求。http://www.codeproject.com/KB/cs/FastMethodInvoker.aspxFastInvoke.GetMethodInvoker(property.GetSetMethod())
    就可以了,返回的是FastInvokeHandler委托。public delegate object FastInvokeHandler(object target, object[] paramters);
    可惜如果是Field就无能为力了,不过这种情况比较少。
      

  21.   

    ewrewwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
      

  22.   

    帅哥,你搬了我 cnblogs 博客上的~~~
      

  23.   

    System;
    using System.Linq;
    using System.Reflection;
    using System.Reflection.Emit;namespace CSharpConsole06
    {
        class Program
        {
            static void Main(string[] args)
            {
                //声明自定义类型,实例化
                TestClass obj = new TestClass();
                //调用静态方法设置值
                FastProperty<TestClass> fp = new FastProperty<TestClass>(obj);
                FastPropertyBufferd<TestClass> fp2 = new FastPropertyBufferd<TestClass>(obj, "Value");
                int tick = Environment.TickCount;
                for (int i = 0; i < 100000; i++)
                {
                    fp.SetPropertyValue("Value", 5000).Invoke(obj, 5000);   
                }
                tick = Environment.TickCount - tick;
                Console.WriteLine("FastProperty".PadRight(20) + " : " + tick.ToString());
                tick = Environment.TickCount;
                for (int i = 0; i < 100000; i++)
                {
                    fp2.SetValue(5000);
                }
                tick = Environment.TickCount - tick;
                Console.WriteLine("FastPropertyBufferd".PadRight(20) + " : " + tick);
                tick = Environment.TickCount;
                for (int i = 0; i < 100000; i++)
                {
                    SetNonePublicPropertyValue(obj, "Value", 5000);
                }
                tick = Environment.TickCount - tick;
                Console.WriteLine("Direct reflect".PadRight(20) + " : " + tick);
                Console.ReadKey();
            }        public class TestClass
            {
                private int _value = 500;
                public int Value
                {
                    get
                    {
                        return _value;
                    }
                    set
                    {
                        _value = value;
                        //Console.WriteLine("Value changed! New value is " + value.ToString());
                    }
                }
            }        /// <summary>
            /// 设置Protected/Private类型的属性值
            /// </summary>
            /// <param name="Owner">要设置的对象</param>
            /// <param name="propertyName">属性名</param>
            /// <param name="value">值</param>
            public static void SetNonePublicPropertyValue(object Owner, string propertyName, object value)
            {
                Owner.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance).ToList().ForEach(p => Console.WriteLine(p.Name));
                //获取非公开的成员属性
                PropertyInfo pi = Owner.GetType().GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Default);
                if (pi != null)//如果获取到了,说明你调用没错
                {
                    pi.SetValue(Owner, value, null);//设置值,这个最后一个属性,是索引值,如果属性本身是Array或List,这里要写索引编号或索引器要求的值。
                }
            }        /// <summary>
            /// 缓存反射结果的类,提高访问速度
            /// </summary>
            /// <typeparam name="T">类型</typeparam>
            public class FastPropertyBufferd<T>
            {
                private T _owner = default(T);
                MethodInfo mi = null;
                public FastPropertyBufferd(T owner,string propertyName)
                {
                    _owner = owner;
                    mi = typeof(T).GetMethod("set_" + propertyName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic);
                }
                public void SetValue(object value)
                {
                    mi.Invoke(_owner, new object[] { value });
                }
            }        public class FastProperty<T>
            {
                public delegate void SetValueDelegateHandler(T owner, object value);
                private readonly Type ParameterType = typeof(object);            private T _owner;
                public T Owner { get { return this._owner; } }            private Type _ownerType;            public FastProperty(T owner)
                {
                    this._owner = owner;
                    this._ownerType = typeof(T);
                }            public void SetPropertyValue2(string propertyName, object value)
                {
                    PropertyInfo[] pis = Owner.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance);
                    foreach (PropertyInfo pi in pis)
                    {
                        if (pi.Name == propertyName)
                        {
                            pi.SetValue(Owner, value, null);
                        }
                    }
                }            public SetValueDelegateHandler SetPropertyValue(string propertyName, object value)
                {
                    // 指定函数名
                    string methodName = "set_" + propertyName;
                    // 搜索函数,不区分大小写 IgnoreCase
                    var callMethod = this._ownerType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic);
                    // 获取参数
                    var para = callMethod.GetParameters()[0];
                    // 创建动态函数
                    DynamicMethod method = new DynamicMethod("EmitCallable", null, new Type[] { this._ownerType, ParameterType }, this._ownerType.Module);
                    // 获取动态函数的 IL 生成器
                    var il = method.GetILGenerator();
                    // 创建一个本地变量,主要用于 Object Type to Propety Type
                    var local = il.DeclareLocal(para.ParameterType, true);
                    // 加载第 2 个参数【(T owner, object value)】的 value
                    il.Emit(OpCodes.Ldarg_1);
                    if (para.ParameterType.IsValueType)
                    {
                        il.Emit(OpCodes.Unbox_Any, para.ParameterType);// 如果是值类型,拆箱 string = (string)object;
                    }
                    else
                    {
                        il.Emit(OpCodes.Castclass, para.ParameterType);// 如果是引用类型,转换 Class = object as Class
                    }
                    il.Emit(OpCodes.Stloc, local);// 将上面的拆箱或转换,赋值到本地变量,现在这个本地变量是一个与目标函数相同数据类型的字段了。
                    il.Emit(OpCodes.Ldarg_0);   // 加载第一个参数 owner
                    il.Emit(OpCodes.Ldloc, local);// 加载本地参数
                    il.EmitCall(OpCodes.Callvirt, callMethod, null);//调用函数
                    il.Emit(OpCodes.Ret);   // 返回
                    /* 生成的动态函数类似:
                     * void EmitCallable(T owner, object value)
                     * {
                     *     T local = (T)value;
                     *     owner.Method(local);
                     * }
                     */
                    return method.CreateDelegate(typeof(SetValueDelegateHandler)) as SetValueDelegateHandler;
                }
            }
        }
    }