一、上一講中描述了反射中常見的類,僅僅是描述類與反射之間的關係。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生成強類型的表單,其實也和反射有關
總結:
這三篇文章都是實際工做中用的較多的一些知識點,但願對不太瞭解的人有所幫助