C#之反射优化

1.什么是反射

菜鸟教程上说,反射指程序可以访问、检测和修改它本身状态或行为的一种能力。我的理解就是,反射就是指可以把字符串作为参数去调用方法的一种能力。
如果把“直接调用某个类型的某个方法”比作是齿轮的工作原理,是一个齿轮直接接触带动另一个齿轮工作的,那么“反射调用某个类型的某个方法”就好像是B超的工作原理,是通过发出超声波并解析反射波来解读物体内部结构的。
我们来举个例子:

    public class Test
    {
        public Test()
        {
            Console.Write("I'm Test. ");
        }
        public void Say()
        {
            Console.WriteLine("Hello everyone! ");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            //直接调用
            new Test().Say();
            //反射调用
            Assembly ass = Assembly.Load("ConsoleApp1");//加载程序集
            Type t = ass.GetType("ConsoleApp1.Test");//加载类
            MethodInfo mt = t.GetMethod("Say");//加载方法

            var obj = Activator.CreateInstance(t);//实例化类
            mt.Invoke(obj, new object[] { });//执行
        }
    }

代码解释:
可以看出:直接调用是强耦合的,需要对Test类进行直接的引用;而反射调用只需要知道目标方法的程序集名,类名和方法名就行了,这大大降低了程序的耦合性,提高了程序的灵活性和扩展性。
但与此同时,由于反射的解释性质,其性能要远低于直接代码,那么有没有什么办法可以既享受到反射的便利又享受到直接调用的性能呢?

2.如何实现反射优化 part1

这里使用Emit和一个单例字典来解决问题。
首先,什么是Emit。
大家知道,编译器会把源代码(C#)编译成托管代码(IL),托管代码在公共语言运行库(CLR)中运行。当方法被调用时,再通过即时编译器(JIT)编译成机器码。而Emit的作用可以理解为直接操作托管代码来生成类或者方法。

这里反射优化的思路就是每次反射调用Test类的Say方法时,优先去一个存放着各种代理类的字典中查找Test的代理类,如果找到了就直接调用Test的代理类中的SayFunction委托,如果找不到则通过Emit生成SayFunction委托,组合成一个代理类,再把组合成的代理类放入字典中等待下次调用。

代码如下:

    class FRType
    {
        #region 属性
        public Type Type { get; set; }
        public delegate object CreaterFunction();
        public CreaterFunction Creater { get; set; }
        public delegate void SayFunction();
        public SayFunction Say { get; set; }
        #endregion
        #region 构造函数
        public FRType(Type type)
        {
            this.Type = type;
            if (!this.Type.IsGenericTypeDefinition)
                this.Creater = CreateCreaterFunction(this.Type);
            this.Say = CreateSayFunction(this.Type);
        }
        #endregion

        #region il
        //***************************************************************************************************************//
        // Evaluation Stack 计算栈,存放值类型和引用地址,unsafe代码优化的目标,节省装箱拆箱操作,遵从FILO原则           //
        // Call Stack中的RecordFrame 局部变量表,方便调用局部变量,不遵从FILO原则                                        //
        // Managed Heep 托管堆,存放引用对象,由GC管理,一般IL不涉及其操作                                               //
        //***************************************************************************************************************//
        public static CreaterFunction CreateCreaterFunction(Type type)
        {
            if (type.IsValueType)
            {
                return () => Activator.CreateInstance(type);
            }
            else
            {
                //预定义要用到的方法
                var type_constructor = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance).First(e => e.GetParameters().Length == 0);
                //定义【参数列表】,注:动态方法是静态的
                var dm = new DynamicMethod("", typeof(Object), new Type[] { }, type, true);
                var il = dm.GetILGenerator();
                //处理【计算栈】,可以模拟一个静态函数,然后使用IL DASM的汇编结果
                il.Emit(OpCodes.Newobj, type_constructor);
                il.Emit(OpCodes.Ret);
                return (CreaterFunction)dm.CreateDelegate(typeof(CreaterFunction));
            }
        }
        public static SayFunction CreateSayFunction(Type type)
        {
            //预定义要用到的方法
            var type_Say = type.GetMethod("Say", BindingFlags.Public | BindingFlags.Instance);
            //定义【参数列表】,注:动态方法是静态的
            var dm = new DynamicMethod("", null, new Type[] { typeof(Object) }, type, true);
            var il = dm.GetILGenerator();
            //处理【计算栈】,可以模拟一个静态函数,然后使用IL DASM的汇编结果
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Call, type_Say);
            il.Emit(OpCodes.Ret);
            return (SayFunction)dm.CreateDelegate(typeof(SayFunction));
        }
        #endregion
    }
    class FRTypeCollection : IEnumerable<FRType>
    {
        #region 单例模式
        private volatile static FRTypeCollection _instance = null;
        private static readonly object lockHelper = new object();
        public static FRTypeCollection Instance()
        {
            if (_instance == null)
            {
                lock (lockHelper)
                {
                    if (_instance == null)
                        _instance = new FRTypeCollection();
                }
            }
            return _instance;
        }
        #endregion
        #region 属性
        private readonly Dictionary<Type, FRType> _Items;
        #endregion
        #region 构造函数
        private FRTypeCollection()
        {
            _Items = new Dictionary<Type, FRType>();
        }
        #endregion
        #region Collection
        public FRType this[Type name]
        {
            get
            {
                FRType value;
                if (!_Items.TryGetValue(name, out value))
                {
                    value = new FRType(name);
                    this.Add(value);
                }
                return value;
            }
        }
        internal void Add(FRType value)
        {
            var name = value.Type;
            FRType p;
            if (!_Items.TryGetValue(name, out p))
            {
                lock (lockHelper)
                {
                    if (!_Items.TryGetValue(name, out p))
                    {
                        _Items.Add(name, value);
                    }
                }
            }
        }
        public bool ContainsKey(Type name)
        {
            return _Items.ContainsKey(name);
        }
        public ICollection<Type> Names
        {
            get { return _Items.Keys; }
        }
        public int Count
        {
            get { return _Items.Count; }
        }
        #endregion
        #region 迭代器
        public IEnumerator<FRType> GetEnumerator()
        {
            foreach (var item in _Items)
            {
                yield return item.Value;
            }
        }
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _Items.Values.GetEnumerator();
        }
        #endregion
    }
    
    public class Test
    {
        public Test()
        {
            Console.Write("I'm Test. ");
        }
        public void Say()
        {
            Console.WriteLine("Hello everyone! ");
        }
    }
    public class Test2
    {
        public Test2()
        {
            Console.Write("I'm Test2. ");
        }
        public void Say()
        {
            Console.WriteLine("Hello everybody! ");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            //直接调用
            new Test().Say();
            new Test2().Say();
            //反射调用
            FRTypeCollection.Instance()[typeof(Test)].Creater();
            FRTypeCollection.Instance()[typeof(Test)].Say();
            FRTypeCollection.Instance()[typeof(Test2)].Creater();
            FRTypeCollection.Instance()[typeof(Test2)].Say();
        }
    }

代码解释:
上述代码中,FRTypeCollection就是存放代理类FRType的单例字典。通过FRTypeCollection调用构造函数和Say方法可以在牺牲第一次调用性能的情况下,大大加速后续调用的性能。断点打到FRType的构造函数中可以发现,当第二次调用FRTypeCollection.Instance()[typeof(Test)].Say()时,已经不会命中这个断点了。

3.如何实现反射优化 part2

上面的part1只是举了一个大概的例子来阐述反射优化的思路,如果反射的类中不包含Say方法就会报错。然而一般情况下,反射往往用在框架代码中,他关心的更多是一些比较通用的方法,比如【1.构造函数;2.属性】。毕竟不是所有的类都有Say方法的。
下面我们就【1.构造函数;2.属性】这两个优化目的重新编写代码:
提前注意的是,一个类的属性个数是未知的,因此,我们给FRType加了一个成员FRPropertyCollection,用于表示其属性的集合。
框架代码如下:

    /// <summary>
    /// Type的代理类,类似于装饰者模式,只不过实现原理从继承变为组合
    /// </summary>
    class FRType
    {
        #region 属性
        public Type Type { get; set; }
        public FRPropertyCollection FRPropertyCollection { get; set; }
        public CreaterFunction Creater { get; set; }
        #endregion
        #region 构造函数
        public FRType(Type type)
        {
            this.Type = type;
            this.FRPropertyCollection = new FRPropertyCollection(Type);
            if (!this.Type.IsGenericTypeDefinition)
                this.Creater = CreateCreaterFunction(this.Type);
        }
        #endregion

        #region il
        //***************************************************************************************************************//
        // Evaluation Stack 计算栈,存放值类型和引用地址,unsafe代码优化的目标,节省装箱拆箱操作,遵从FILO原则           //
        // Call Stack中的RecordFrame 局部变量表,方便调用局部变量,不遵从FILO原则                                        //
        // Managed Heep 托管堆,存放引用对象,由GC管理,一般IL不涉及其操作                                               //
        //***************************************************************************************************************//
        public static CreaterFunction CreateCreaterFunction(Type type)
        {
            if (type.IsValueType)
            {
                return () => Activator.CreateInstance(type);
            }
            else
            {
                //预定义要用到的方法
                var type_constructor = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance).First(e => e.GetParameters().Length == 0);
                //定义【参数列表】,注:动态方法是静态的
                var dm = new DynamicMethod("", typeof(Object), new Type[] { }, type, true);
                var il = dm.GetILGenerator();
                //处理【计算栈】,可以模拟一个静态函数,然后使用IL DASM的汇编结果
                il.Emit(OpCodes.Newobj, type_constructor);
                il.Emit(OpCodes.Ret);
                return (CreaterFunction)dm.CreateDelegate(typeof(CreaterFunction));
            }
        }
        #endregion
    }
    class FRTypeCollection : IEnumerable<FRType>
    {
        #region 单例模式
        private volatile static FRTypeCollection _instance = null;
        private static readonly object lockHelper = new object();
        public static FRTypeCollection Instance()
        {
            if (_instance == null)
            {
                lock (lockHelper)
                {
                    if (_instance == null)
                        _instance = new FRTypeCollection();
                }
            }
            return _instance;
        }
        #endregion
        #region 属性
        private readonly Dictionary<Type, FRType> _Items;
        #endregion
        #region 构造函数
        private FRTypeCollection()
        {
            _Items = new Dictionary<Type, FRType>();
        }
        #endregion
        #region Collection
        public FRType this[Type name]
        {
            get
            {
                FRType value;
                if (!_Items.TryGetValue(name, out value))
                {
                    value = new FRType(name);
                    this.Add(value);
                }
                return value;
            }
        }
        internal void Add(FRType value)
        {
            var name = value.Type;
            FRType p;
            if (!_Items.TryGetValue(name, out p))
            {
                lock (lockHelper)
                {
                    if (!_Items.TryGetValue(name, out p))
                    {
                        _Items.Add(name, value);
                    }
                }
            }
        }
        public bool ContainsKey(Type name)
        {
            return _Items.ContainsKey(name);
        }
        public ICollection<Type> Names
        {
            get { return _Items.Keys; }
        }
        public int Count
        {
            get { return _Items.Count; }
        }
        #endregion
        #region 迭代器
        public IEnumerator<FRType> GetEnumerator()
        {
            foreach (var item in _Items)
            {
                yield return item.Value;
            }
        }
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _Items.Values.GetEnumerator();
        }
        #endregion
    }
    public class FRProperty
    {
        #region 属性
        public string Name { get; set; }//用于检索FRProperty

        public Type PropertyType { get; set; }//属性的类型
        public IEnumerable<string> Attributes { get; set; }//属性上的所有标签
        public bool IsArray { get; set; }
        public bool IsList { get; set; }
        public Type elementType { get; set; }//若是Array,IList或可空类型,则为其元素的类型,反之为null
        public bool IsNullable { get; set; }


        public delegate object GetterFunction(object obj);
        public GetterFunction Getter { get; set; }//Getter的方法
        public delegate void SetterFunction(object obj, object value);
        public SetterFunction Setter { get; set; }//Setter的方法
        #endregion
        #region 构造函数
        public FRProperty(PropertyInfo prop)
        {
            this.Name = prop.Name;

            this.PropertyType = prop.PropertyType;
            this.IsArray = this.PropertyType.IsArray;
            this.IsList = string.Compare(this.PropertyType.Name, "List`1") == 0;

            this.Attributes = from e in prop.GetCustomAttributes(true) select e.GetType().Name;

            this.IsNullable = this.PropertyType.IsGenericType && this.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>));
            this.elementType = this.IsArray ? this.PropertyType.GetElementType() : (this.IsList || this.IsNullable ? this.PropertyType.GetGenericArguments()[0] : null);

            this.Getter = CreateGetterFunction(prop);
            this.Setter = CreateSetterFunction(prop);
        }
        #endregion
        #region il
        //***************************************************************************************************************//
        // Evaluation Stack 计算栈,存放值类型和引用地址,unsafe代码优化的目标,节省装箱拆箱操作,遵从FILO原则           //
        // Call Stack中的RecordFrame 局部变量表,方便调用局部变量,不遵从FILO原则                                        //
        // Managed Heep 托管堆,存放引用对象,由GC管理,一般IL不涉及其操作                                               //
        //***************************************************************************************************************//
        public static GetterFunction CreateGetterFunction(PropertyInfo prop)
        {
            Type ReflectedType = prop.ReflectedType;
            Type DeclaringType = prop.DeclaringType;
            Type PropertyType = prop.PropertyType;
            //预定义要用到的方法
            var met = ReflectedType.GetMethod("get_" + prop.Name);
            if (met == null)
                return null;
            //定义【参数列表】,注:动态方法是静态的
            var dm = new DynamicMethod("", typeof(Object), new Type[] { typeof(Object) }, ReflectedType, true);
            var il = dm.GetILGenerator();
            //定义【局部变量列表】
            //il.DeclareLocal(type);
            //处理【计算栈】,可以模拟一个静态函数,然后使用IL DASM的汇编结果
            if (met.IsStatic)
            {
                il.Emit(OpCodes.Call, met);
            }
            else
            {
                il.Emit(OpCodes.Ldarg_0);
                if (DeclaringType.IsValueType)
                {
                    il.Emit(OpCodes.Unbox_Any, DeclaringType);
                    if (Nullable.GetUnderlyingType(DeclaringType) == null)
                    {
                        var t = il.DeclareLocal(DeclaringType);
                        il.Emit(OpCodes.Stloc, t);
                        il.Emit(OpCodes.Ldloca_S, t);
                    }
                }
                else
                {
                    il.Emit(OpCodes.Castclass, DeclaringType);
                }
                if (DeclaringType.IsValueType)
                {
                    il.Emit(OpCodes.Call, met);
                }
                else
                {
                    il.Emit(OpCodes.Callvirt, met);
                }
            }
            if (PropertyType.IsValueType)
            {
                il.Emit(OpCodes.Box, PropertyType);
            }
            il.Emit(OpCodes.Ret);
            return (GetterFunction)dm.CreateDelegate(typeof(GetterFunction));
        }
        public static SetterFunction CreateSetterFunction(PropertyInfo prop)
        {
            Type ReflectedType = prop.ReflectedType;
            Type DeclaringType = prop.DeclaringType;
            Type PropertyType = prop.PropertyType;
            //预定义要用到的方法
            var set = ReflectedType.GetMethod("set_" + prop.Name);
            if (set == null)
                return null;
            //定义【参数列表】,注:动态方法是静态的
            var dm = new DynamicMethod("", null, new Type[] { typeof(Object), typeof(Object) }, ReflectedType, true);
            var il = dm.GetILGenerator();
            //定义【局部变量列表】
            //il.DeclareLocal(type);
            //处理【计算栈】,可以模拟一个静态函数,然后使用IL DASM的汇编结果
            if (set.IsStatic)
            {
                il.Emit(OpCodes.Ldarg_1);
                if (PropertyType.IsValueType)
                {
                    il.Emit(OpCodes.Unbox_Any, PropertyType);
                }
                else
                {
                    il.Emit(OpCodes.Castclass, PropertyType);
                }
                il.Emit(OpCodes.Call, set);
            }
            else
            {
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Castclass, DeclaringType);
                il.Emit(OpCodes.Ldarg_1);
                if (PropertyType.IsValueType)
                {
                    il.Emit(OpCodes.Unbox_Any, PropertyType);
                }
                else
                {
                    il.Emit(OpCodes.Castclass, PropertyType);
                }
                il.Emit(OpCodes.Callvirt, set);
            }
            il.Emit(OpCodes.Ret);
            return (SetterFunction)dm.CreateDelegate(typeof(SetterFunction));
        }
        #endregion
    }
    public class FRPropertyCollection : IEnumerable<FRProperty>
    {
        #region 属性
        public Dictionary<string, FRProperty> _Items;
        #endregion
        #region 构造函数
        public FRPropertyCollection(Type type)
        {
            _Items = new Dictionary<string, FRProperty>();
            foreach (var p in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))//指搜索包含公共的实例成员
            {
                if (p.GetIndexParameters().Length == 0) //排除索引器,一般的属性是不含参数的
                {
                    if (!this.ContainsKey(p.Name))//防止重复添加
                    {
                        var a = new FRProperty(p);
                        this.Add(a);
                    }
                }
            }
        }
        #endregion
        #region Collection
        public FRProperty this[string name, bool exactitude = true]
        {
            get
            {
                FRProperty value = null;
                if (exactitude)
                {
                    _Items.TryGetValue(name, out value);
                }
                else
                {
                    foreach (FRProperty p in this)
                    {
                        if (string.Compare(p.Name, name, true) == 0)
                        {
                            value = p;
                            break;
                        }
                    }
                }
                return value;
            }
        }
        internal void Add(FRProperty value)
        {
            var name = value.Name;
            FRProperty p;
            if (!_Items.TryGetValue(name, out p))
            {
                _Items.Add(name, value);
            }
        }
        public bool ContainsKey(string name)
        {
            return _Items.ContainsKey(name);
        }
        public ICollection<string> Names
        {
            get { return _Items.Keys; }
        }
        public int Count
        {
            get { return _Items.Count; }
        }
        #endregion
        #region 迭代器
        public IEnumerator<FRProperty> GetEnumerator()
        {
            foreach (var item in _Items)
            {
                yield return item.Value;
            }
        }
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _Items.Values.GetEnumerator();
        }
        #endregion
    }
    public delegate object CreaterFunction();

业务代码如下:

    public class Point
    {
        public int X { get; set; }
        public int Y { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Point p = new Point();
            p.X = 1;
            p.Y = 123;

            int x = (int)FRTypeCollection.Instance()[typeof(Point)].FRPropertyCollection["X"].Getter(p);
            int y = (int)FRTypeCollection.Instance()[typeof(Point)].FRPropertyCollection["Y"].Getter(p);
        }
    }

4.如何实现反射优化 part3

虽然在part2中实现了由字符串"X"去获取Point实例p的X值,但是调用起来比较麻烦,而且万一某个属性是一个复杂对象呢?例如:

    public class Circle
    {
        public Point O { get; set; }
        public int R { get; set; }
    }
    public class Point
    {
        public int X { get; set; }
        public int Y { get; set; }
    }

要获取Circle的圆心O的X值,用part2的调用方式显然是很困难的。
所以,这里使用扩展方法对调用方式进行一个优化。在part2的框架代码中添加如下代码:

    /// <summary>
    /// 快速反射,扩展了object,可以从object中快速地反射出所需要的内容
    /// </summary>
    public static class ExtendObject_FR
    {
        /// <summary>
        /// FastRefrectionGet方法,支持链式查询和模糊查询
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="name"></param>
        /// <param name="exactitude"></param>
        /// <returns></returns>
        public static object FRGet(this object obj, string name, bool exactitude = true)
        {
            string[] names = name.Split('.');
            int index;
            int beginIndex = 0;
            if (int.TryParse(names[0], out index))
            {
                beginIndex = 1;
                obj = ((IList)obj)[index];
            }
            return obj.FRGetObj(names, beginIndex, exactitude);
        }
        /// <summary>
        /// FastRefrectionSet方法,支持链式设置和模糊设置
        /// 若链中有不存在的属性,则break出来,返回最后一个break前一个节点
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <param name="exactitude"></param>
        public static object FRSet(this object obj, string name, object value, bool exactitude = true)
        {
            string[] names = name.Split('.');
            int index;
            int beginIndex = 0;
            if (int.TryParse(names[0], out index))
            {
                beginIndex = 1;
                Type objtype = obj.GetType();
                bool isList = string.Compare(objtype.Name, "List`1") == 0;
                if (!isList)
                {
                    return obj;
                }
                Type elementType = objtype.GetGenericArguments()[0];
                IList list = (IList)obj;
                AddToNum(list, index, elementType);
                if (list[index] == null)
                {
                    list[index] = elementType.FRCreate();
                }
                obj = list[index];
            }
            return obj.FRSetObj(names, beginIndex, value, exactitude);
        }

        private static object FRGetObj(this object obj, string[] names, int beginIndex, bool exactitude = true)
        {
            int index;
            for (int i = beginIndex, count = names.Length - beginIndex; i < count; i++)
            {
                if (int.TryParse(names[i], out index))
                {
                    obj = ((IList)obj)[index];
                }
                else
                {
                    obj = obj.FRGetObjOnce(names[i], exactitude);
                }
            }
            return obj;
        }
        private static object FRSetObj(this object obj, string[] names, int beginIndex, object value, bool exactitude = true)
        {
            int count = names.Length;
            object parent;
            int index;
            bool isjump = false;
            if (count >= 2 + beginIndex)
            {
                for (int i = beginIndex; i < count - 1; i++)
                {
                    parent = obj;
                    FRProperty objtype = parent.GetType().FRGetPropertis()[names[i], exactitude];
                    if (objtype == null)
                    {
                        isjump = true;
                        break;
                    }
                    if (objtype.IsList)
                    {
                        i++;
                        int.TryParse(names[i], out index);
                        IList list = (IList)parent.FRGet(names[i - 1], exactitude);
                        if (list == null)
                        {
                            list = (IList)(objtype.PropertyType.FRCreate());
                        }
                        list = AddToNum(list, index, objtype.elementType);
                        if (i < count - 1)
                        {
                            if (list[index] == null)
                            {
                                list[index] = objtype.elementType.FRCreate();
                            }
                            obj = list[index];
                        }
                        else
                        {
                            if (index >= 0)
                                list[index] = value;
                            isjump = true;
                            obj = value;
                        }
                        parent.FRSetObjOnce(names[i - 1], list, exactitude);
                    }
                    else if (objtype.IsArray)
                    {
                        i++;
                        int.TryParse(names[i], out index);
                        IList arr = (IList)parent.FRGet(names[i - 1], exactitude);
                        if (arr == null)
                        {
                            arr = Array.CreateInstance(objtype.elementType, index + 1);
                        }
                        if (arr.Count < index + 1)
                        {
                            Array newArray = Array.CreateInstance(objtype.elementType, index + 1);
                            Array.Copy((Array)arr, 0, newArray, 0, arr.Count);
                            arr = newArray;
                        }
                        if (i < count - 1)
                        {
                            if (arr[index] == null)
                            {
                                arr[index] = objtype.elementType.FRCreate();
                            }
                            obj = arr[index];
                        }
                        else
                        {
                            if (index >= 0)
                                arr[index] = value;
                            isjump = true;
                            obj = value;
                        }
                        parent.FRSetObjOnce(names[i - 1], arr, exactitude);
                    }
                    else
                    {
                        obj = parent.FRGetObjOnce(names[i], exactitude);
                        if (obj == null)
                        {
                            obj = parent.FRSetObjOnce(names[i], objtype.PropertyType.FRCreate(), exactitude);
                        }
                    }
                }
            }
            if (!isjump)
            {
                FRProperty objtype = obj.GetType().FRGetPropertis()[names[count - 1], exactitude];
                if (objtype != null)
                {
                    obj = obj.FRSetObjOnce(names[count - 1], value, exactitude);
                }
            }
            return obj;
        }
        private static object FRGetObjOnce(this object obj, string name, bool exactitude = true)
        {
            FRProperty frp = FRTypeCollection.Instance()[obj.GetType()].FRPropertyCollection[name, exactitude];
            return frp.Getter(obj);
        }
        private static object FRSetObjOnce(this object obj, string name, object value, bool exactitude = true)
        {
            FRProperty frp = FRTypeCollection.Instance()[obj.GetType()].FRPropertyCollection[name, exactitude];
            if (value == DBNull.Value)
            {
                value = null;
            }
            if (value != null && value.GetType() != frp.PropertyType)
            {
                Type type;
                if (!frp.IsNullable)
                    type = frp.PropertyType;
                else
                    type = frp.elementType;

                if (type.IsEnum)
                    value = Enum.Parse(type, value.ToString());
                else
                    value = Convert.ChangeType(value, type);
            }
            frp.Setter(obj, value);
            return value;
        }
        private static IList AddToNum(IList list, int num, Type type)
        {
            while (list.Count < num + 1)
            {
                list.Add(type.IsValueType ? type.FRCreate() : null);
            }
            return list;
        }
    }
    public static class ExtendType_FR
    {
        /// <summary>
        /// FastReflection获得属性集合
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static FRPropertyCollection FRGetPropertis(this Type type)
        {
            return FRTypeCollection.Instance()[type].FRPropertyCollection;
        }
        public static object FRCreate(this Type type)
        {
            return FRTypeCollection.Instance()[type].Creater();
        }
        public static CreaterFunction FRCreateFunction(this Type type)
        {
            return (FRTypeCollection.Instance()[type].Creater);
        }
    }

业务代码:

    public class Circle
    {
        public Point O { get; set; }
        public int R { get; set; }
    }
    public class Point
    {
        public int X { get; set; }
        public int Y { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Point p = new Point();
            p.X = 1;
            p.Y = 123;
            Circle c = new Circle();
            c.O = p;
            c.R = 999;

            int c_x = (int)c.FRGet("O.X");
            int c_y = (int)c.FRGet("O").FRGet("Y");
            int r = (int)c.FRGet("R");
        }
    }

代码解释:
实际上,ExtendObject_FR只是对调用方式进行了一个封装。使之支持循环调用。当循环到O的时候去FRTypeCollection中寻找/创建Circle的代理类,当循环到X的时候去FRTypeCollection中寻找/创建Point的代理类。所以,c.FRGet(“O.X”)是等效于c.FRGet(“O”).FRGet(“X”)的。这样,调用起来就非常方便了。

5.总结

反射在框架代码中被大量的使用,其性能的优化是必须的。本文采用了“空间换时间”的思路,牺牲第一次调用的性能,把Emit创建的委托放在内存中来提高之后调用的性能。

以上就是反射优化的全部内容,如有纰漏和建议,欢迎大家留言指出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值