C#反射回顾笔记

一 、反射概述

反射提供描述程序集、模块和类型的对象(Type 类型)。 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型,然后调用其方法或访问其字段和属性。 如果代码中使用了特性,可以利用反射来访问它们。

反射在以下情况下很有用:

  • 需要访问程序元数据中的特性时。 

  • 检查和实例化程序集中的类型。

  • 在运行时构建新类型。

  • 执行后期绑定,访问在运行时创建的类型上的方法。 

二 、Type对象

Type:表示类型声明:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。

如何获取Type?

1. Type t =  typeof(String); String可以是其他类型

2. Type t =  String.GetType();

3. Type t = Type.GetType("System.String"); 及相关重载,注意参数包含命名空间

更多方式参见 https://docs.microsoft.com/zh-cn/dotnet/api/system.type?view=netframework-4.7.2

三 、Assembly对象

Assembly:使用 Assembly 来定义和加载程序集,加载程序集清单中列出的模块,以及在此程序集中定位一个类型并创建一个它的实例。

如何获取Assembly?

1. 加载程序集的建议的方法是使用Load方法,它标识要按其显示名称加载的程序集 (例如,"System.Windows.Forms、 版本 = 2.0.0.0,区域性 = 中性,PublicKeyToken = b77a5c561934e089")。

Assembly assembly=Assembly.Load("System");  参数为名称空间

2. LoadFileLoadFrom方法为在其中必须由路径标识程序集的极少数情况下提供。

Assembly a = Assembly.LoadFile(@"D:C#ReflectTestReflectTestdllUtility.dll");  dll或exe全路径

Assembly a = Assembly.LoadForm(@"D:C#ReflectTestReflectTestdllUtility.dll");

3. ReflectionOnlyLoadReflectionOnlyLoadFrom方法可加载为反射,而不是执行程序集。 与Load,LoadForm类似

四 、获取指定程序集类的方法

public static void Main(string[] args)
        {
            Assembly a = Assembly.Load("ReflectTest");
            Type t = a.GetType("ReflectTest.Program");
            var isnt = Activator.CreateInstance(t);
            foreach (var method in t.GetMethods())
            {
                //激活方法
                method.Invoke(t, null);
            }
        }

参数由第二个入参确定,一般多个参数建议使用object传入(当入参变更时可以减少代码修改)

如需获取私有等方法可以使用重载public MethodInfo GetMethod(string name, BindingFlags bindingAttr);等借助BindingFlags对象实现。

 五 、获取指定程序集类的属性

public static void Main(string[] args)
        {
            Assembly a = Assembly.Load("ReflectTest");
            Type t = a.GetType("ReflectTest.Program");
            var isnt = Activator.CreateInstance(t);
            foreach (var propt in t.GetProperties())
            {
                
                Console.WriteLine(propt.Name);
            }
        }

应用:利用反射将dataTable填充至泛型对象

/// <summary>
        /// DataTable利用泛型填充实体类
        /// </summary>
        /// <typeparam name="T">实体类</typeparam>
        /// <param name="table">dt</param>
        /// <returns></returns>
        public static IList<T> DataTableToList<T>(DataTable table)
        {
            IList<T> list = new List<T>();
            T t = default(T);
            PropertyInfo[] propertypes = null;
            string tempName = string.Empty;
            foreach (DataRow row in table.Rows)
            {
                t = Activator.CreateInstance<T>();
                propertypes = t.GetType().GetProperties();
                foreach (PropertyInfo pro in propertypes)
                {
                    tempName = pro.Name;
                    if (table.Columns.Contains(tempName))
                    {
                        string value = row[tempName].ToString();
                        pro.SetValue(t, value, null);
                    }
                }
                list.Add(t);
            }
            return list;
        }
原文地址:https://www.cnblogs.com/xieyang07/p/10409856.html