*Attribute特性
1、属性案例
1、定制特性可以应用的目标元素包括:程序集(assembly)、模块(module)、类型(type)、属性(proprety)、事件(event)、字段(field)、方法(method)、参数(param)、返回值(return),不外乎这些。
2、定制特性以[,]的形式展现,放在紧挨的元素上,多个特性可以应用于同一元素,特性间以逗号隔开,以下表达规则都是有效的:
1、Flags
[Flags] //标识枚举类型,引用时得到的是前面的Dog,而不是0x0001; enum Animal { Dog = 0x0001, Cat = 0x0002, Duck = 0x0004, Chicken = 0x0008 } Animal animals = Animal.Dog | Animal.Cat; //Dog,Cat,如果没有Flags特性,这里的结果将是"3"
2.Obsolete 废弃的
/// <summary> /// Obsolete 废弃的,已过时的; /// 第一个参数可以任意文本,第二个参数默认为false只是警告,改为true时显示错误 /// </summary> [Obsolete("Don't use Old method, use New method", true)] public static void Old() { }
3、DllImport
DllImport特性,可以让我们调用非托管代码,所以我们可以使用DllImport特性引入对Win32 API函数的调用。
4、Serializable
Serializable特性表名了应用的元素可以被序列化。
5、Conditional
Conditional特性,用于条件编译,在调试时使用。
2、自定义特性类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; namespace ConsoleApp1 { /* * 1、System.Attribute派生出我们自己的特性类(一个从System.Attribute抽象类继承而来的类,不管是直接还是间接继承,都会成为一个特性类; * 2、使用Attribute为后缀; * 3、AttributeUsage控制自定义特性的使用规则: * 第一个参数:通过AttributeTargets枚举列出可以放在那些类型前面Class、Field、All... * 第二个参数:是否可以重复放在同一个程序实体多次 * 第三个参数:该特性可以被继续 */ [AttributeUsage(AttributeTargets.Class, AllowMultiple =false, Inherited =false)] public class HelpAttribute : Attribute { protected string _description; public string Description { get { return this._description; } } public HelpAttribute(string str) { this._description = str; } } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
Assembly, Module, Class, Struct, Enum, Constructor, Method, Property, Field, Event, Interface, Parameter, Delegate, All = Assembly | Module | Class | Struct | Enum | Constructor | Method | Property | Field | Event | Interface | Parameter | Delegate, ClassMembers = Class | Struct | Enum | Constructor | Method | Property | Field | Event | Delegate | Interface )
3、Demo
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* 1、比较继承自Attribute类,命名最好以Attribute结尾 2、本质上是一个类,为目标元素提供提供关联的附加信息,并在运行时以反射的方式来获取附件信息。 3、实例是在编译期进行初始化,而不是运行期 */ [AttributeUsage(AttributeTargets.All)] public class ColumnAttribute : Attribute { public string CName { get; set; } public string CAlias { get; set; } public ColumnAttribute(string name) { this.CName = name; } } public class SysUserInfo { /*实例化时在([])里调用构造函数完成的,构造函数中参数是特性后面的括号中传进去的,如UserID便是构造函数的参数; 属性赋值直接传递给构造函数的参数后面进行赋值的,如CAlias="用户账号" */ [Column("UserID", CAlias = "用户账号")] public string UserID { get; set; } }
4、登录
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[CheckLogin] //此处为自定义属性,要引用相应的命名空间 public ActionResult Index() { return View(); } public ActionResult Login() //此Action自动往cookie里写入登录信息 { HttpCookie hcUserName = new HttpCookie("username","admin"); HttpCookie hcPassWord = new HttpCookie("password","123456"); System.Web.HttpContext.Current.Response.SetCookie(hcUserName); System.Web.HttpContext.Current.Response.SetCookie(hcPassWord); return View();
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class CheckLogin : ActionFilterAttribute { //在Action执行之前 乱了点,其实只是判断Cookie用户名密码正不正确而已而已。 public override void OnActionExecuting(ActionExecutingContext filterContext) { HttpCookieCollection CookieCollect = System.Web.HttpContext.Current.Request.Cookies;if (CookieCollect["username"] == null || CookieCollect["password"] == null) { filterContext.Result = new RedirectResult("/Home/Login"); } else { if (CookieCollect["username"].Value != "admin" && CookieCollect["password"].Value != "123456") { filterContext.Result = new RedirectResult("/Home/Login"); } } } }