反射的使用及其使用场景
1、什么是反射
在.net程序运行的时候会将各种对象中的数据、对象的名称、对象的类型这些信息保存在元数据中,元数据保存在程序集中,我们访问并操作元数据或者程序集的行为就叫反射。举个栗子:我们在代码中实例化的对象是一座房子,但是程序编译运行时的基本单位不是房子,而是砖。程序把这座房子解析成了一块块砖,我们访问、操作这些砖需要把它还原成一座房子。具体来说,把一个对象解析成元数据,再把元数据还原成另一个对象的行为叫反射,但是只要访问了,就使用了对象,所以我说访问并操作元数据或者程序集的行为就叫反射。当然了,这是个人理解。
2、如何使用反射
使用GetType()或者typeof()方法获取一个type类,这个类就包含了该对象的所有信息。下面用代码举例一些反射的基本用法:
/// <summary> /// 反射用的类 /// </summary> public class TypeofModel { [Description("这是id")] public int Id { get; set; } [Description("这是编码")] public string No { get; set; } } //下面是调用的代码 var typeofModel = new TypeofModel() { Id = 1, No = "第一" }; var t = typeofModel.GetType(); var cols = t.GetFields();//获取所有字段 var properties = t.GetProperties();//获取所有属性 foreach (var v in properties) { string str = ""; str += v.Name;//获取属性名称 str += v.PropertyType;//获取属性类型 str += v.GetValue(typeofModel);//获取属性值 object[] attributes = v.GetCustomAttributes(true);//获取该属性值的所有特性 foreach (var m in attributes) { var childProperties = m.GetType().GetProperties();//获取所有属性 foreach (var n in childProperties) { str += n.GetValue(m);//获取属性值 } } }
3、反射的应用场景
保存数据的时候可以使用反射验证数据的简单信息,这里我们只验证string类型,代码如下:
public class ValidationAttribute : Attribute { public ValidationAttribute(int maxLength, string name, bool isRequired) { MaxLength = maxLength; Name = name; IsRequired = isRequired; } public int MaxLength { get; set; } public string Name { get; set; } public bool IsRequired { get; set; } } public static class ValidationModel { public static (bool,string) Validate(object obj) { var t = obj.GetType(); var properties = t.GetProperties();//获取所有属性 foreach (var property in properties) { if (!property.IsDefined(typeof(ValidationAttribute), false)) continue;//验证是否加上ValidationAttribute标记 object[] objs = property.GetCustomAttributes(typeof(ValidationAttribute), true);//获取特性 var firstValidation = (ValidationAttribute)objs[0]; var maxLength = firstValidation.MaxLength; var name = firstValidation.Name; var isRequired = firstValidation.IsRequired; //获取属性的值 var propertyValue = property.GetValue(obj) as string; if (string.IsNullOrEmpty(propertyValue) && isRequired) { return (false, $"{name}不可为空"); } if (!string.IsNullOrEmpty(propertyValue) && propertyValue.Length > maxLength) { return (false, $"{name}长度不可超过{maxLength}"); } } return (true,""); } }
/// <summary> /// 反射用的类 /// </summary> public class TypeofModel { [Description("这是id")] public int Id { get; set; } [Validation(64,"编码",true)] public string No { get; set; } }
var model = new TypeofModel() { Id = 1, No = "" }; var msg = ValidationModel.Validate(model); if (!msg.Item1) { throw new Exception(msg.Item2); }