Unity自定义属性(Attribute)示例

  • Post author:
  • Post category:其他


一.自定义属性,使用场景

a.想知道当前的工程内定义过的特定的类

b.想知道当前工程内,类中定义过的特定的成员(变量,方法)

二.自定义属性介绍

a.需要继承自 System.Attrbute。 可以有自己的成员

b.Attribute参数说明:

参数一:代表该属性使用的位置。例如:field, method, class等,详细看枚举

参数二:字面意思,是否允许多个存在

参数三:表示派生类,是否也拥有该属性。 True:表示拥有

c. 示例代码:field的使用自定义属性

    [AttributeUsage(AttributeTargets.Field, AllowMultiple=true, Inherited=true)]
    public class TestFieldAttribute : System.Attribute
    {
        private string _name;
        public string name => _name;
            
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="UIName">编辑器上显示的名字</param>
        public TestFieldAttribute(string UIName)
        {
            _name = UIName;
        }
    }
    
    [AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=false)]
    public class TestClassAttribute : System.Attribute
    {
        private string _name;
        public string name => _name;
            
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="UIName">编辑器上显示的名字</param>
        public TestClassAttribute(string UIName)
        {
            _name = UIName;
        }
    }
    
    [AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=false)]
    public class TestMethodAttribute : System.Attribute
    {
        private string _name;
        public string name => _name;
            
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="UIName">编辑器上显示的名字</param>
        public TestMethodAttribute(string UIName)
        {
            _name = UIName;
        }
    }

d.使用示例:注意使用的时候可以省略掉Attribute,语言支持的

    [TestClass("测试类")]
    public class ThisIsClass
    {
        [TestField("测试属性")]
        [TestField("测试属性")]
        public string thisIsField;
        
        [TestMethod("测试方法")]
        public void TestMethod()
        {
            
        }
    }

三.如果获取加过指定自定义属性的类,成员

思路:扫描当前工程内所有的类,所有的属性。判定其自定义属性,与自定义属性是否相等

a. 获取工程内添加过自定义属性的类,示例

private static void GetTestAttrType()
{
    var doMain = AppDomain.CurrentDomain;
    // var assemblies = doMain.ReflectionOnlyGetAssemblies(); 也可以通过反射
    var assemblies = doMain.GetAssemblies();
    
    // 遍历,所有的程序集
    for (int i = 0; i < assemblies.Length; i++)
    {
        //TODO 此处可以过滤掉不需要的程序集,提升效率
        var assembly = assemblies[i];
        var types = assembly.GetTypes();
        // 遍历程序集内所有的类型
        for (int j = 0; j < types.Length; j++)
        {
            var typeNameSpace = types[j].Namespace;
            // 过滤命名空间,提升效率
            if (string.IsNullOrEmpty(typeNameSp!typeNameSpace.Equals("命名空间"))
                continue;
            // 过滤掉泛型, 可有可无
            if (types[j].IsGenericTypeDefinition)
                continue;
            var attr = types[j].GetCustomAttribute<TestClassAttribute>();
            if (attr == null)
                continue;
            // 此处识别到了添加了指定自定义属性的Type,以及属性中的值
            Type targetType = types[j];
            string uiName = attr.name;
        }
    }
}

b.识别添加了自定义属性的成员,示例代码

private static Dictionary<string, FieldInfo> GetTestFieldAttrs(Type actionType)
{
    Dictionary<string, FieldInfo> result = new Dictionary<string, FieldInfo>();
    
    var flag = BindingFlags.Instance | BindingFlags.Public;
    var fields = actionType.GetFields(flag);
    if (fields == null || fields.Length <= 0)
    {
        return result;
    }
    for (int i = 0; i < fields.Length; i++)
    {
        var attr = fields[i].GetCustomAttribute<TestFieldAttribute>();
        if (attr != null)
        {
            // 此处识别到了添加了指定自定义属性的成员,以及属性中的值
            result.Add(attr.name, fields[i]);
        }
    }
    return result;
}



版权声明:本文为qq_26444231原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。