zoukankan      html  css  js  c++  java
  • 关于Unity中的涉及到Attribute的相关概念整理(@WhiteTaken)

    这两天事情比较多,没有来得及更新,现在把我这两天看的attributes相关内容进行整理。

    涉及到的相关概念包括:

    • C#中的特性概念及用法
    • 创建自己的特性以及通过反射访问特性

    C#中的特性概念以及用法:

      这个特性的概念,我还是比较喜欢称之为注解属性,官网上的定义,

    特性具有以下属性:

    • 特性可向程序中添加元数据。 元数据是有关在程序中定义的类型的信息。 所有的 .NET 程序集都包含指定的一组元数据,这些元数据描述在程序集中定义的类型和类型成员。 可以添加自定义特性,以指定所需的任何附加信息。 

    • 可以将一个或多个特性应用到整个程序集、模块或较小的程序元素(如类和属性)。

    • 特性可以与方法和属性相同的方式接受参数。

    • 程序可以使用反射检查自己的元数据或其他程序内的元数据。

      其实说白了,就是程序中的"[]"中括号之中的内容。

      一个声明中可以放置多个特性,某些特性可以多次赋给一个声明。

      某些特性对于给定实体可以指定多次。 例如,ConditionalAttribute 就是一个可多次使用的特性:

      

    1 [Conditional("DEBUG"), Conditional("TEST1")]
    2 void TraceMethod()
    3 {
    4      // ...
    5 }

      这里需要注意一点,根据约定,所有特性名称都以单词“Attribute”结束,以便将它们与“.NET Framework”中的其他项区分。 但是,在代码中使用特性时,不需要指定 attribute 后缀。 例如,[DllImport] 虽等效于 [DllImportAttribute],但 DllImportAttribute 才是该特性在 .NET Framework 中的实际名称。

    特性的参数:

      许多特性都有参数,而这些参数可以是定位参数、未命名参数或命名参数。 任何定位参数都必须按特定顺序指定并且不能省略,而命名参数是可选的且可以按任意顺序指定。 首先指定定位参数。 例如,这三个特性是等效的:

    [DllImport("user32.dll")]  
    [DllImport("user32.dll", SetLastError=false, ExactSpelling=false)]  
    [DllImport("user32.dll", ExactSpelling=false, SetLastError=false)]  

    特性的目标:

      特性的目标是应用该特性的实体。 例如,特性可以应用于类、特定方法或整个程序集。 默认情况下,特性应用于它后面的元素。 但是,您也可以显式标识要将特性应用于方法还是它的参数或返回值。显示的应用特性目标,可以这样:

    [target : attribute-list]  

      target值的列表如下:

      样例用法:

    • 将特性应用于程序集和模块

      

    using System;
    using System.Reflection;
    [assembly: AssemblyTitleAttribute("Production assembly 4")]
    [module: CLSCompliant(true)]
    • 在 C# 中将特性应用于方法、方法参数和方法返回值
    // default: applies to method
    [SomeAttr]
    int Method1() { return 0; }
    
    // applies to method
    [method: SomeAttr]
    int Method2() { return 0; }
    
    // applies to return value
    [return: SomeAttr]
    int Method3() { return 0; }

      无论规定 SomeAttr 应用于什么目标,都必须指定 return 目标,即使 SomeAttr 被定义为仅应用于返回值也是如此。 换言之,编译器将不使用 AttributeUsage 信息解析不明确的特性目标。


    创建自己的特性以及通过反射访问特性:

    直接上代码:(创建自己的特性)

     1 using UnityEngine;
     2 using System.Collections;
     3 using System;
     4 
     5 [AttributeUsage(AttributeTargets.Class|AttributeTargets.Field,     //特性应用的目标           
     6                           AllowMultiple=true,                      //是否可以在同一目标上放置多次
     7                           Inherited=false)]                        //是否允许子类使用此特性
     8 public class myattr : Attribute {
     9 
    10     private string name;
    11     public int version = 0;                                        //命名参数
    12     public myattr(string _name) {
    13         name = _name;
    14         version = 1;
    15     }
    16 
    17     public string GetInputName() {
    18         return name;
    19     }
    20 }

    接下来使应用特性,并通过反射访问特性.

    using UnityEngine;
    using System.Collections;
    using System;
    using System.Reflection;
    
    [myattr("WhiteTaken1", version = 2)]
    public class MyTest1 { }
    [myattr("WhiteTaken2", version = 2), myattr("WhiteTaken3", version = 1)]
    public class MyTest2 { }
    [myattr("WhiteTaken4")]
    public class MyTest3 { }
    public class MyTest4 { }
    public class TestMyattr: MonoBehaviour {
        
        void Start () {
            PrintMyattrInfo(typeof(MyTest1));
            PrintMyattrInfo(typeof(MyTest2));
            PrintMyattrInfo(typeof(MyTest3));
            PrintMyattrInfo(typeof(MyTest4));
        }
    
        void PrintMyattrInfo(Type _type) {
            
            Debug.Log("--打印信息--" + _type);
            //应用反射
            Attribute[] att = Attribute.GetCustomAttributes(_type);
            //遍历特性
            foreach (Attribute everyAttr in att) {
                if (everyAttr is myattr) {
                    myattr _myattr = (myattr)everyAttr;
                    Debug.Log("version=" + _myattr.version + ",Name=" + _myattr.GetInputName());
                }
            }
            Debug.Log("----------------------分隔符------------------------");
        }
    }

    运行结果:

    创建自己的特性,需要继承System.Attribute类,并在自己的特性类之前应用AttributeUsage特性,并设置应用目标AttributeTargets,枚举类型成员如下。

     AllowMultiple是允许在一个目标上应用多次,如果为false,则只存在当前特性的一个,如果为true,当前特性可以添加多次,并用","隔开。

    Inherited为false,子类不继承父类的特性。

    基本的用法,接下来就是应用到自己的程序当中,另外附上一个github中看到的自定义特性的地址

    未完,待续。。。

  • 相关阅读:
    随手练——几个递归小题目
    随手练——USACO 1.44 母亲的牛奶
    随手练——汉诺塔问题(递归典型)
    Linux搭建lamp(Apache+PHP+Mysql环境)centos7.2版详细教程
    Windows 环境下安装redis 及其PHP Redis扩展
    Windows系统如何安装Redis
    phpstorm配置成sublime的代码高亮逼格风格
    phpstorm-----实现实时编辑服务器代码
    如何在Webstorm/Phpstorm中设置连接FTP,并快速进行文件比较,上传下载,同步等操作
    phpstorm取消自动保存,修改快捷键并标识修改的文件为星星标记
  • 原文地址:https://www.cnblogs.com/WhiteTaken/p/6265516.html
Copyright © 2011-2022 走看看