首页 > 代码库 > .Net实战之反射操作篇
.Net实战之反射操作篇
1、上一讲中描述了反射中常见的类,仅仅是描述类与反射之间的关系。
但是实际是对数据的操作, 在反射中,数据如何操作?
[MyTable("T_UserInfo")] public class UserInfo : Person, UserService { private static string nickname; private int _age2; private int _age; [DisplayName("年龄")] public int Age { get { return _age; } set { _age = value; } } [DisplayName("姓名")] public string Name { get; set; } public void ShowUserInfo() { Console.WriteLine(string.Format("name:{0},age:{1}", Name, _age)); } protected void ShowName() { Console.WriteLine("showName:" + Name); } }
UserInfo ui=null;//这样写,无论获取或设置数据,都会引发异常。
UserInfo ui=new UserInfo();//基于这种情况,我们必须创建类的实例,才能获取或设置数据。
既然反射与类有那么多的对应关系(上一讲图片),那么我们可以猜测,是不是获取到类的实例才能操作数据呢?
于是就有了下图:
2、创建类的实例 一般用以下3种
--程序集指定类型名称
UserInfo assCreateInstanceUser = ass.CreateInstance("ReflectionDemo.UserInfo") as UserInfo;
--Type类型创建
Type t = ass.GetType("ReflectionDemo.UserInfo", false, true);UserInfo ActivatorUserInfo = Activator.CreateInstance(t) as UserInfo;//还可以CreateInstance(string assemblyName, string typeName)等方法
--构造函数获取实例
//获取无参数构造函数 ConstructorInfo ci = t.GetConstructor(new Type[] { }); //调用无参数构造函数,返回对象 object obj = ci.Invoke(new object[] { }); //获取有参数构造函数 ConstructorInfo ci2 = t.GetConstructor(new Type[] { typeof(string)}); //调用有参数构造函数(参数值与构造函数参数类型对应) object obj2 = ci2.Invoke(new object[] { "有参数name"});
--3、操作字段、属性、方法
//==============字段 //获取私有字段、存在于实例成员中如_age FieldInfo fiAge = t.GetField("_age", BindingFlags.NonPublic | BindingFlags.Instance); fiAge.SetValue(assCreateInstanceUser, 20);//设置字段_age的值为20 Console.WriteLine("字段age===="+fiAge.GetValue(assCreateInstanceUser)); //获取字段_age值 //nickname为静态,公有字段 FieldInfo fiStatic = t.GetField("nickname", BindingFlags.Public | BindingFlags.Static); // fiStatic.SetValue(null, "hello");//静态字段可以传入对象或null //fiStatic.GetValue(null);//静态字段可以传入对象或null //==============属性 PropertyInfo pi = t.GetProperty("Name");//获取属性Name //t.GetProperty("Name", BindingFlags.Public | BindingFlags.Instance);//还可以设置位标记等 pi.SetValue(assCreateInstanceUser, "zhangsan");//设置属性Name的值为zhangsan Console.WriteLine("属性Name====" + pi.GetValue(assCreateInstanceUser)); //获取属性Name值 //==============方法 //公有方法 MethodInfo miShowUserInfo = t.GetMethod("ShowUserInfo", new Type[] { }); object retMethodObj = miShowUserInfo.Invoke(assCreateInstanceUser, new object[] { }); //非公开方法,有返回值 MethodInfo miGetUserInfo = t.GetMethod("GetUserInfo", BindingFlags.NonPublic|BindingFlags.Instance,null,new Type[] { },null); object retMethodObj2 = miGetUserInfo.Invoke(assCreateInstanceUser, new object[] { });
--4、反射案例1 显示枚举Description
public enum AuditStateEnum { [Description("等待审核")] WAIT_AUDIT = 1, [Description("审核通过")] PASS = 2, [Description("审核不通过")] NOT_PASS = 4 }
非反射的做法一般如下:
private void ShowEnumDesc() { BindEnumToDropdownlist(ddl1, typeof(AuditStateEnum)); } private void BindEnumToDropdownlist(DropDownList ddl, Type enumType) { foreach (int i in Enum.GetValues(enumType)) { ListItem li2 = new ListItem(Enum.GetName(enumType, i), i.ToString()); ddl.Items.Add(li2); } }
反射的做法如下:
private void BindEnumDescToDropdownlist(DropDownList ddl, Type enumType) { FieldInfo[] fiList = enumType.GetFields(BindingFlags.Public | BindingFlags.Static); foreach (FieldInfo fi in fiList) { DescriptionAttribute descAttr = fi.GetCustomAttribute(typeof(DescriptionAttribute), false) as DescriptionAttribute; if (descAttr != null) { ddl.Items.Add(new ListItem(descAttr.Description,Convert.ToInt32(fi.GetValue(null)).ToString()); } } }
---
--5、反射案例2 生成查询sql
static string createQuerySql<TEntity>() where TEntity : class,new() { Type objType = typeof(TEntity); TEntity entity = new TEntity(); var props =objType.GetProperties(BindingFlags.Public|BindingFlags.Instance); StringBuilder sbSql = new StringBuilder(" select "); foreach (var prop in props) { if (prop.CanWrite) { sbSql.Append(","+prop.Name); } } sbSql.AppendFormat(" from {0}", objType.Name); string sql = sbSql.ToString(); return sql.Remove(sql.IndexOf(‘,‘),1); }
--6、mvc 特性过滤,打上ignoreCheck标签的controller或action无需权限校验
public class IgnoreCheckAttribute : Attribute { } public class CheckRightAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { //是否无需校验 if (filterContext.ActionDescriptor.IsDefined(typeof(IgnoreCheckAttribute), false)) { } base.OnActionExecuting(filterContext); } public override void OnActionExecuted(ActionExecutedContext filterContext) { base.OnActionExecuted(filterContext); } public override void OnResultExecuting(ResultExecutingContext filterContext) { base.OnResultExecuting(filterContext); } public override void OnResultExecuted(ResultExecutedContext filterContext) { base.OnResultExecuted(filterContext); } }
--7、mvc生成强类型的表单,其实也和反射有关
总结:
这三篇文章都是实际工作中用的较多的一些知识点,希望对不太了解的人有所帮助
.Net实战之反射操作篇
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。