C#特性
来源:互联网 发布:2016奥运女排数据 编辑:程序博客网 时间:2024/05/18 00:27
<1>
C#特性学习笔记
特性标签的本质:
1>特性是一个类,这个类的声明我们有一个规范,即:以Attribute结尾,例如MyClassAttribute 。当着仅仅是一个规范,如果你是在不以Attribute结尾也没关系。
2>这个类一定要继承自Attribute类。只有继承Attribute类,这个类才是一个特性
注意点:比如一个特性类的名称是MyClassAttribute ,当我们在某个类,方法,属性,字段贴这个特性标签的时候,可以省略它后面的Attribute 直接这样贴就可以 ,如:[MyClass] 当然 你也可以写全称,如[MyClassAttribute]
既然[MyClass] 等于 new MyClassAttribute() 那么很多逻辑就在特性的构造函数中去实现。然后再有需要的类或者其成员上打上特性标签
系统自带特性的介绍
using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace WebApplication1{ //Attribute 类 //TypeId属性: 当在派生类中实现时,获取该 Attribute 的唯一标识符。 //AttributeUsageAttribute 类 (AttributeUsageAttribute 类是继承自 Attribute 的) //AttributeUsageAttribute.Inherited 属性:获取或设置一个布尔值,该值指示指示的属性能否由派生类和重写成员继承。如果该属性可由派生类和重写成员继承,则为 true,否则为 false。默认为 true。 //AttributeUsageAttribute.AllowMultiple 属性:获取或设置一个布尔值,该值指示能否为一个程序元素指定多个指示属性实例。如果允许指定多个实例,则为 true;否则为 false。默认为 false。 //AttributeUsageAttribute.ValidOn 属性:获取一组值,这组值标识指示的属性可应用到的程序元素。属性值:一个或多个 AttributeTargets 值。默认为 All。 //注意:对于一个特性类使用Attribute后缀是一个惯例。然而,如果不添加编译器会自动添加匹配。 //限定特性类的应用范围 (这里规定ClassMsg这个特性类只能用于类和字段) [AttributeUsage(AttributeTargets.Class | AttributeTargets.Field, AllowMultiple = true, Inherited = false)] //定制MsgAttribute特性类,继承于Attribute public class ClassMsgAttribute : Attribute { //定义_msg字段和Msg属性//Msg属性用于读写msg字段 string _msg; public string Msg { get { return _msg; } set { _msg = value; } } public ClassMsgAttribute() { } //重载构造函数接收一个参数,赋值给_msg字段 public ClassMsgAttribute(string s) { _msg = s; } } //---------------------调用ClassMsg这个特性---------------------// //在Person类上标记ClassMsg特性 [ClassMsg(Msg = "这是关于人的姓名信息的类")] class Person { //在_name字段上应用ClassMsg特性 [ClassMsg("这是存储姓名的字段")] string _name; //以下特性无法应用,因为MsgAttribute定义的特性只能用于类和字段 //[ClassMsg("这是读写姓名字段的属性")] public string Name { get { return _name; } set { _name = value; } } } }
另外我们在来看看系统自带的一个[Obsolete] 特性,这个特性的作用就是标记某个方法是否已经过时的
例如:
定义一个Pigcs类
using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace 特性学习{ public class Pigcs { [Obsolete("此方法已经过时,请调用新的方法NewEat()")] //这个Obsolete特性是专门用来告诉用户某些方法或成员已经过时的消息 public string OldEat() { return "我是老的方法"; } public string NewEat() { return "我是新的方法"; } }}我们定义了这个Pigcs类,并在它的OldEat()方法上使用了[Obsolete]这个系统特性。看看效果怎么样
我们在来看看微软自带的这个ObsoleteAttribute特性类
自定义特性,及自定义特性的继承
自定义特性的定义
using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace 特性学习{ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] public class VipAttribute : Attribute //自定义一个Vip特性 { } public class Vip5Attribute : VipAttribute //此时Vip5Attribute类也是一个特性了。它默认继承了父类的[AttributeUsage(AttributeTargets.Class| AttributeTargets.Method,AllowMultiple=true,Inherited=true)] { } //现在问题来了: Vip5Attribute继承了VipAttribute,因为VipAttribute这个特性只能用于类和方法,那么这个Vip5Attribute也就只能用在类,和方法上面,那假如我们这个Vip5Attribute想用在类和方法和属性上怎么办呢? //答案很简单,只要在Vip5Attribute这个特性上加系统特性就好了,如下: //只要在Vip5Attribute类上打上 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method |AttributeTargets.Property] 就可以了。 //特别要注意,如果在子类上不打特性标签,就默认继承父类的特性标签,但是如果在子类上打了特性标签,就等于覆盖了父类的特性标签。 //例如在子类上打: [AttributeUsage(AttributeTargets.Class] 那么它就只能用于类,而不能像父类那样用于方法 //[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method |AttributeTargets.Property, AllowMultiple = true, Inherited = true)] //public class Vip5Attribute : VipAttribute //{ //}}
实现一个登陆验证的特性
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.SessionState;namespace 检查登陆验证.Attributes{ [AttributeUsage(AttributeTargets.Class)] //这个特性只能用于类 public class CheckLoginAttribute : Attribute //定义一个名字叫CheckLoginAttribute 的特性,用户检查用户是否已经登录 { //我们知道在一个类上打上[CheckLogin] 就等于 new CheckLoginAttribute() 所以我们在这里定义了这个CheckLoginAttribute特性的不带参数的构造函数,在构造函数中判断用户是否已经登录。如果用户未登录,那么就跳到Login.aspx页面 public CheckLoginAttribute() { if (HttpContext.Current.Session["UserName"] == null) { HttpContext.Current.Response.Redirect("Login.aspx"); } } }}
特性还有其他的用法
定义一个特性
using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace 特性学习{ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method|AttributeTargets.Field|AttributeTargets.Property, AllowMultiple = true, Inherited = true)] public class VipAttribute : Attribute //自定义一个Vip特性 { string name; public string Name { get { return name; } } public VipAttribute(string disName) { this.name = disName; //构造函数初始化私有字段name } }}
假如我有两个类。一个是Pig类(猪) 一个是Dog类 (狗)
Pig类
using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace 特性学习{ public class Pig { [Vip("猪名字")] public string Name { get; set; } [Vip("猪年龄")] public int Age { get; set; } }}Dog类
using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace 特性学习{ public class Dog { [Vip("狗名字")] public string Name { get; set; } [Vip("狗年龄")] public int Age { get; set; } }}
根据需求,其实实际就是根据类型来获取类型属性上的的特性标签里的参数值
用法:
首先创建一个WebFrom页面
WebForm1.aspx文件
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="特性学习.WebForm1" %><!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title></head><body> <form id="form1" runat="server"> <div> </div> <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label> <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> <br /> <asp:Label ID="Label2" runat="server" Text="Label"></asp:Label> <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox> </form></body></html>WebFrom1.aspx.cs文件
using System;using System.Collections.Generic;using System.Linq;using System.Reflection;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;namespace 特性学习{ public partial class WebForm1 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { /* Pig p = new Pig(); Type t = p.GetType(); //获取Pig类中的Name属性 PropertyInfo propName = t.GetProperty("Name"); PropertyInfo propAge = t.GetProperty("Age"); //检查Name这个属性上有没有[Vip]这个特性标签 bool bName = propName.IsDefined(typeof(VipAttribute)); bool bAge = propAge.IsDefined(typeof(VipAttribute)); if (bName) { //如果Name属性上有[Vip]这个特性标签,那么就获取这个特性标签 Attribute attr = propName.GetCustomAttribute(typeof(VipAttribute)); VipAttribute vip = attr as VipAttribute; //转换一下类型 this.Label1.Text = vip.Name; } if (bAge) { //如果Name属性上有[Vip]这个特性标签,那么就获取这个特性标签 Attribute attr = propAge.GetCustomAttribute(typeof(VipAttribute)); VipAttribute vip = attr as VipAttribute; //转换一下类型 this.Label2.Text = vip.Name; } */ //----------------------优化一下代码------------------------ Pig pp = new Pig(); //根据类型来获取类型对应的属性特性标记值,如获取这个[VIP(猪名字)]特性标记里的”猪名字“ // Dog pp = new Dog(); Type tt = pp.GetType(); //获取Pig类型的所有属性 PropertyInfo[] pros = tt.GetProperties(); //遍历属性 foreach (var a in pros) { //VipAttribute vipattr = a.GetCustomAttribute<VipAttribute>(); //这样写。或者下面的写法 //获取这个属性上的[vip]标签 Attribute attr = a.GetCustomAttribute(typeof(VipAttribute)); //类型转换 VipAttribute vip = attr as VipAttribute; switch (a.Name) { case "Name": this.Label1.Text = vip.Name; break; case "Age": this.Label2.Text = vip.Name; break; } } } }}
0 0
- C# 特性
- C#特性
- c#特性
- C#特性
- C#特性
- C# 特性
- C# 特性
- C# 特性
- C#特性
- c# 特性
- C#中的特性,什么是特性.
- C# C# Attribute特性 (四)
- C#2.0的特性
- C#2.0的特性
- C# 及其特性
- C#2.0 Partial 特性
- C# 及其特性
- c#2.0新特性
- 如何在 iOS 真机运行 Appium
- Makefile之写demo时的通用Makefile写法总结
- sublime之xdebug浏览器插件
- 排列组合的求法&next_permutation
- MPEG简介
- C#特性
- 微软安装包中 Redistributable 和 runtime 的区别
- 远程连接Oracle数据库
- Quick-Cocos2d-x UI控件之滑动条(UISlider)控件
- 中电信12月运营数据:移动用户1.86亿 3G占63%
- 给不同的按钮设置同样的点击listener,在listener内部根据不同的按钮分别处理
- Android开源:数据库ORM框架GreenDao学习心得及使用总结
- eclipse常用快捷键
- Android四种存储方式 sharedpreference,file,SQlite,contentprovider实现增删改查