博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
.NET基础 (18)特性
阅读量:5208 次
发布时间:2019-06-14

本文共 5336 字,大约阅读时间需要 17 分钟。

特性

 

特性

1 什么是特性,如何自定义一个特性

特性是一种特殊的用以申明式编程的机制,特性类型是一族继承自System.Attribute的类型,在编译时,特性的使用会被写入元数据中,以共运行或者程序中的反射使用。自定义一个特性,本质上是定义一个继承自System.Attribute的类型。

自定义特性示例:

///     /// 自定义的特性    ///     [AttributeUsage(AttributeTargets.Class)]    public class MyAttribute : Attribute    {        private String _classname;        public MyAttribute(String s)        {            _classname = s;        }        //一个只读属性        public String ClassName        {            get            {                return _classname;            }        }    }    ///     /// 使用自定义属性    ///     [MyAttribute("UseMyAttribute")]    class UseMyAttribute    {        static void Main(string[] args)        {            Type t = typeof(UseMyAttribute);            Object[] attributes = t.GetCustomAttributes(false);            MyAttribute att = (MyAttribute)attributes[0];            Console.WriteLine(att.ClassName);            Console.Read();        }    }

输出:

UseMyAttribute

特性将被写入元数据中,所以特性的使用基本都基于反射机制。

有几点需要注意:

  • 按照惯例,特性的名字都以Attribute结尾。
  • C#中,为了使用方便,可以省略特性名字后缀Attribute,如 [MyAttribute("UseMyAttribute")] 可写为 [My("UseMyAttribute")]。
  • 特性自身可以添加其他特性。

2 .NET中特性可以在哪些元素上使用

特性可以应用在程序集、模块、结构、枚举、构造方法、方法、属性、字段、事件、接口、参数、委托、返回参数和泛型参数这些目标元素上。通过AttributeUsage特性可以限制自定义特性的使用范围。

示例:

using System;//应用在程序集上[assembly: MyAttribute]//应用在模块上[module: MyAttribute]//应用在类型上[type: MyAttribute]class AttributeTargets<[typevar: MyAttribute] T> //泛型参数上{    //应用在字段上    [field: MyAttribute]    private String _MyString;    //应用在构造方法上    [method: MyAttribute]    public AttributeTargets()    {    }    //应用在属性上    [property: MyAttribute]    public String MyString    {        get        {            return _MyString;        }    }    //应用在方法上    [return: MyAttribute]    public String Format(        //应用在方法参数上        [param: MyAttribute]String f)    {        return null;    }    //应用在事件上    [event: MyAttribute]    public event EventHandler MyEvent;}/// /// 一个空的特性/// 可用于所有元素/// public class MyAttribute : System.Attribute{}public class MainClass{    static void Main(string[] args)    {    }}

 

 

3 有哪几种方法可以获知一个元素是否申明某个特性

System.Attribute.IsDefined

System.Attribute.GetCustomAttribute

System.Attribute.GetCustomAttributes

System.Reflection.CustomAttributeData

示例:

[My("GetAttributes")]    class GetAttributes    {        static void Main(string[] args)        {            Type attributeType = typeof(MyAttribute);            Type thisClass = typeof(GetAttributes);            //使用IsDefined方法            bool defined = Attribute.IsDefined(                        thisClass,                        attributeType);            Console.WriteLine(                 "GetAttributes类型是否申明了MyAttribute特性:{0}",                 defined.ToString());            //使用Attribute.GetCustomAttribute方法            Attribute att = Attribute.GetCustomAttribute(                        thisClass,                        attributeType);            if (att != null)            {                Console.WriteLine(                    "GetAttributes类型申明了MyAttribute特性。");                Console.WriteLine("名字为:{0}",                     ((MyAttribute)att).Name);            }            //使用Attribute.GetCustomAttributes方法            Attribute[] atts = Attribute.GetCustomAttributes(                            thisClass,                            attributeType);            if (atts.Length > 0)            {                Console.WriteLine(                     "GetAttributes类型申明了MyAttribute特性。");                Console.WriteLine("名字为:{0}",                     ((MyAttribute)atts[0]).Name);            }            //使用System.Reflection.CustomAttributeData类型            IList
list = CustomAttributeData.GetCustomAttributes(thisClass); if (list.Count > 0) { Console.WriteLine( "GetAttributes类型申明了MyAttribute特性。"); //注意这里可以对特性进行分析,但不能得到其实例 CustomAttributeData attdata = list[0]; Console.WriteLine("特性的名字是:{0}", attdata.Constructor.DeclaringType.Name); Console.WriteLine("特性的构造方法有{0}个参数。", attdata.ConstructorArguments.Count); } Console.Read(); } } ///
/// 一个简单的特性 /// [AttributeUsage(AttributeTargets.All)] public sealed class MyAttribute : Attribute { private String _name; public MyAttribute(String s) { _name = s; } public String Name { get { return _name; } } }

 

输出:

GetAttributes类型是否申明了MyAttribute特性:True

GetAttributes类型申明了MyAttribute特性。
名字为:GetAttributes
GetAttributes类型申明了MyAttribute特性。
名字为:GetAttributes
GetAttributes类型申明了MyAttribute特性。
特性的名字是:MyAttribute
特性的构造方法有1个参数。
4 一个元素是否可以重复申明同一个特性

当一个特性申明了AttributeUsage特性并且显示地将AllowMultiple属性设置为true时,该特性就可以在同一元素上多次申明,否则的话编译器将被报错。

示例:

[My("Class1")]    [My("Class2")]    [My("Class1")]    class AllowMultiple    {        static void Main(string[] args)        {        }    }    ///     /// 使用AttributeUsage限定使用范围    /// 并且允许在同一元素上多次申明    ///     [AttributeUsage(AttributeTargets.Class,AllowMultiple=true)]    class MyAttribute : Attribute    {        private String _s;        public MyAttribute(String s)        {            _s = s;        }    }

 

 

 

转载请注明出处:

作者:

出处:

转载于:https://www.cnblogs.com/jesselzj/p/4802413.html

你可能感兴趣的文章
JS 多种变量定义
查看>>
redis可执行文件说明
查看>>
ajax向后台传递数组
查看>>
剑指offer系列14:包含min函数的栈
查看>>
疯狂JAVA16课之对象与内存控制
查看>>
[转载]树、森林和二叉树的转换
查看>>
WPF移动Window窗体(鼠标点击左键移动窗体自定义行为)
查看>>
Java核心技术梳理-类加载机制与反射
查看>>
1593: [Usaco2008 Feb]Hotel 旅馆 (线段树)
查看>>
软件测试-----Graph Coverage作业
查看>>
POJO 与 JavaBean 的区别 !
查看>>
php、mysql查询当天,查询本周,查询本月的数据实例(字段是时间戳)
查看>>
Windows Phone 7手势识别左右滑动 非XNA
查看>>
django ORM创建数据库方法
查看>>
Win8下,以管理员身份启动VS项目
查看>>
[bzoj1025][SCOI2009]游戏 (分组背包)
查看>>
BZOJ 1629 [Usaco2005 Nov]Cow Acrobats:贪心【局部证明】
查看>>
生活中的设计模式
查看>>
对伪静态网站实施注射
查看>>
个人作业1——四则运算题目生成程序(基于控制台)
查看>>