.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生成強類型的表單,其實也和反射有關

總結: 

   這三篇文章都是實際工作中用的較多的一些知識點,希望對不太了解的人有所幫助


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM