zoukankan      html  css  js  c++  java
  • .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生成强类型的表单,其实也和反射有关

    总结: 

       这三篇文章都是实际工作中用的较多的一些知识点,希望对不太了解的人有所帮助

  • 相关阅读:
    熟悉常用的Linux操作
    组合数据类型练习
    简易的词法分析程序
    大数据概述
    201552040205 关于对java的体验与感悟
    对已学习的java内容的一些感悟
    关于java中的一些小技巧
    Javase 大纲2
    Javase大纲
    MysQL知识整理
  • 原文地址:https://www.cnblogs.com/zjflove/p/5868094.html
Copyright © 2011-2022 走看看