.Net實戰之反射操做篇

一、上一講中描述了反射中常見的類,僅僅是描述類與反射之間的關係。html

      可是實際是對數據的操做,  在反射中,數據如何操做? sql

   [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;//這樣寫,不管獲取或設置數據,都會引起異常。mvc

    UserInfo ui=new UserInfo();//基於這種狀況,咱們必須建立類的實例,才能獲取或設置數據。ide

    既然反射與類有那麼多的對應關係(上一講圖片),那麼咱們能夠猜想,是否是獲取到類的實例才能操做數據呢函數

   因而就有了下圖:ui

    

二、建立類的實例 通常用如下3種spa

    --程序集指定類型名稱3d

    UserInfo assCreateInstanceUser = ass.CreateInstance("ReflectionDemo.UserInfo") as UserInfo;                                              

   --Type類型建立 code

Type t = ass.GetType("ReflectionDemo.UserInfo", false, true);
UserInfo ActivatorUserInfo = Activator.CreateInstance(t) as UserInfo;//還能夠CreateInstance(string assemblyName, string typeName)等方法

 

    --構造函數獲取實例orm

            //獲取無參數構造函數
            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"});

 

--三、操做字段、屬性、方法

            //==============字段
            //獲取私有字段、存在於實例成員中如_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[] { });

 

 --四、反射案例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());
                } 
            }
        }

 

        ---  

 --五、反射案例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);
        }

 --六、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);
        }
    } 

 

 --七、mvc生成強類型的表單,其實也和反射有關

總結: 

   這三篇文章都是實際工做中用的較多的一些知識點,但願對不太瞭解的人有所幫助

相關文章
相關標籤/搜索