.net基础--反射
1、什么是反射
元数据是指程序以及类型信息的数据,它包含在程序集中(程序集包含:元数据,编译代码,资源)。
在.net中反射是查看和操作元数据的动作。
2、为什么要用反射
- 在程序运行时,动态加载需要的程序集,以便操作其元数据。(例如有些IOC容器的实现,就是通过配置对应程序集,在运行时动态加载这些程序集,实现注入)
- 构造出可重用性的代码,通过反射可以动态的绑定/获取数据(例如orm中将查询结果转成实体,在更新数据时需要获取实体信息构造更新语句)。
3、.net中使用反射常用的类型
1)Assembly
当我们需要加载程序集时,可以通过Assembly.LoadFrom,或者Assembly.LoadFile方法加载指定程序集。有了程序集我们就可以获取程序集中类型了。
2)Type
Type(类型),我们可以通过Assembly.GetType获取指定的类型,也可以通过Assembly.GetTypes获取程序集中所有的类型。
当然我们也可以通过GetType方法获取变量的类型,还可以使用typeof获取指定类型。
Type中常用方法(以下方法都有对应根据名称获取相应类型的方法,也是很常用,此处略过):
上面列举的方法都有相应重载方法,通过BindingFlags(使用位运算)指定获取对应的类型
例如获取实例非公有方法:
var privateMethods = type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic);
BindingFlags(以下仅列举常用的,详情可以参考BindingFlags枚举信息)
//仅类型内部声明的(不包含父类型的) DeclaredOnly = 2, //实例成员 Instance = 4, //静态成员 Static = 8, //公有 Public = 16, //非公有 NonPublic = 32, ...
简单代码示例
View Code
反射泛型方法,需要调用MakeGenericMethod指定参数实际类型。
View Code
在实际项目中用到的关于反射例子
一、.netcore中依赖注入业务服务
1 #region 服务注入 2 Assembly assembly = Assembly.Load("qingy.Service"); 3 List<Type> types = assembly.GetTypes().Where(p => p.IsClass && !p.IsAbstract && !p.IsGenericType 4 && p.GetInterfaces().Any(x => x == typeof(IService)) 5 ).ToList(); 6 foreach (var item in types) 7 { 8 services.AddTransient(item); 9 10 } 11 #endregion
二、通过反射获取枚举的描述信息
1 public static Dictionary<string, string> GetEnumDescription(Type enumType) 2 { 3 var result = new Dictionary<string, string>(); 4 var fields = enumType.GetFields(); 5 foreach (var item in fields) 6 { 7 if (item.FieldType.IsEnum) 8 { 9 object[] descriptionAttributes = item.GetCustomAttributes(typeof(DescriptionAttribute), false); 10 result.Add(item.Name, descriptionAttributes.Length < 1 ? item.Name : ((DescriptionAttribute)descriptionAttributes[0]).Description); 11 } 12 } 13 return result; 14 }
三、使用反射构造实体映射(略)
4、反射性能非常差?不要用反射?
待定
特性(Attribute)
特性(Attribute),是指.net公共语言运行时允许添加类似关键字的声明信息。它可以声明在类、属性、方法等元数之上。
特性一般都是为元素添加附加的关键信息,通常是通过反射得到这些附件信息进行对应的处理。
常见的特性:Serializable,JsonProperty,MaxLength,DllImport等等。
自定义特性
[AttributeUsage(AttributeTargets.All,AllowMultiple =false,Inherited =false)] public class CommentAttribute:Attribute { /// <summary> /// 备注 /// </summary> public string CommentString { get; set; } /// <summary> /// 长度 /// </summary> public int Length { get; set; } }
说明:
1、特性必须继承自Attribute;
2、在特性类之上添加AttributeUsage可以定义特性的使用范围(通过AttributeTargets限定声明的元素;通过AllowMultiple限定是否可以多次声明,通过Inherited限定继承关系)
3、使用[]包住声明到对应的元素之上即可。
标签:反射,Assembly,item,程序,获取,类型,转载 From: https://www.cnblogs.com/zhangfengggg/p/17238685.html