zoukankan      html  css  js  c++  java
  • <NET CLR via c# 第4版>笔记 第18章 定制特性

    18.1 使用定制特性

    • FCL 中的几个常用定制特性.

      • DllImport 特性应用于方法,告诉 CLR 该方法的实现位于指定 DLL 的非托管代码中.
      • Serializable 特性应用于类型,告诉序列化格式化器一个实例的字段可以序列化和反序列化.
      • AssemblyVersion 特性应用于程序集,设置程序集的版本号.
      • Flags特性应用于枚举类型,枚举类型就成了位标志集合.
    • C# 允许用一个前缀明确指定特性要应用于的目标元素.有时可省略,编译器能推断;有时则必须指定前缀.

    using System;
    
    [assembly: SomeAttr]                    //应用于程序集
    [module: SomeAttr]                      //应用于模块
    
    [type: SomeAttr]                        //应用于类型
    internal sealed class SomeType<[typevar: SomeAttr] T> //应用于泛型类型变量
    {
        [field: SomeAttr]                   //应用于字段
        public int SomeField = 0;
    
        [return: SomeAttr]                  //应用于返回值
        [method: SomeAttr]                  //应用于方法
        public int SomeMethod(
            [param: SomeAttr]               //应用于参数
            int someParam) { return someParam; }
    
        [property: SomeAttr]                //应用于属性
        public string SomeProp {
            [method: SomeAttr]              //应用于get访问器方法
            get { return null; }
        }
    
        [event: SomeAttr]                   //应用于事件
        [field: SomeAttr]                   //应用于编译器生成的字段
        [method: SomeAttr]                  //应用于编译器生成的add & remove方法
        public event EventHandler SomeEvent;
    }
    
    • CLS 要求定制特性类必须直接或间接从公共抽象类 System.Attribute 派生.
    • 应用特性时,c# 编译器允许省略 Attribute 后缀以减少打字量,并提升源代码的可读性.
    • 特性是类的实例,语法类似于调用类的某个实例构造器.如:
        [DllImport("Kernel32", CharSet = CharSet.Auto, SetLastError = true)]
    
    • "Kernel32" 是构造器的参数,称为定位参数,必须指定.
    • CharSetSetLastError 用于设置字段或属性,称为命名参数,是可选的.
    • 在C#中,既可将每个特性都封闭到一对方括号中,也可在一对方括号中封闭多个以逗号分隔的特性.如果特性类的构造器不获取参数,那么圆括号也可以省略,如:
      • [Serializable][Flags]
      • [Serializable,Flags]
      • [FlagsAttribute,SerializableAttribute]
      • [FlagsAttribute(), SerializableAttribute()]

    18.2 定义自己的特性类

      1. Attribute 继承; 2) 类名有 Attribute 后缀(非必须).
    • AttributeUsage 特性是一个简单的类,可利用它告诉编译器定制特性的合法应用范围.所有编译器都内建了对该特性的支持.如:
        [AttributeUsage(AttributeTargets.Enum, Inherited = false)]
        public class FlagsAttribute : Attribute
        {
            public FlagsAttribute() { }
        }
    
    • AttributeUsageAttribute 类有一个公共构造器,它允许传递位标志来指明特性的合法应用范围.
    • AttributeUsageAttribute 类有两个公共属性.其中 AllowMultiple 指示是否允许将该特性多次应用于同一个目标元素; Inherited 指出特性在应用于基类时,是否同时应用于派生类和重写的方法.
    • 如果忘记向自己的特性类应用 AttributeUsageAttribute 特性,则特性类默认为应用于所有目标元素,向每个目标元素都只能应用一次,而且可继承.

    18.3 特性构造器和字段/属性数据类型

    • 定义特性类的实例构造器字段和属性时,只允许Boolean,Char,Byte,SByte,Int16,UInt16,Int32,UInt32,Int64,UInt64,Single,Double,String,Type,Object 或枚举类型.
    • 应用特性时必须传递一个编译时常量表达式,它与特性类定义的类型匹配.
    • 定制特性: 它是类的实例,被序列化成驻留在元数据中的字节流.远行时可对元数据中的字节进行反序列化,从而构造出类的实例.

    18.4 检测定制特性

    • 有三个方法可以获取与目标关联的特性: IsDefined,GetCustomAttributesGetCustomAttribute
    • IsDefined 比另外两个方法更高效,因为 IsDefined 不会构造特性对象,不会调用构造器,也不会设置字段和属性.

    18.5 两个特性实例的相互匹配

    • System.Attribute 重写了 ObjectEquals 方法,利用反射来比较两个特性对象中的字段值(为每个字段都调用 Equals).所有字段都匹配就返回 true ; 否则返回 false.建议重写 Equals 来移除反射的使用.
    • System.Attribute 还公开了虚方法 Match ,其默认实现只是调用 Equals 方法并返回它的结果.

    18.6 检测定制特性时不创建从Attribute派生的对象

    18.7 条件特性类

  • 相关阅读:
    php中global和$GLOBALS[]的分析之一
    javascript 标签 src 链接动态文件。
    Allegro基本操作——PCB布线
    AMD单桥主板上电时序的详细解释
    AMD单双桥时序简叙
    AMD移动FP5平台时序解释
    orcad元件属性批量修改(通过excel表格)
    加减乘除基本函数
    1.excel如何让一列的数都乘以固定值
    ORCAD元件属性白色区域和黄色区域的理解
  • 原文地址:https://www.cnblogs.com/harry-wang/p/7403371.html
Copyright © 2011-2022 走看看