Unity中使用自定义Attribute

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014732824/article/details/82789229

Attribute是c#的语言特性

msdn说明如下:

The Attribute class associates predefined system information or user-defined custom information with a target element. A target element can be an assembly, class, constructor, delegate, enum, event field,interface, method, portable executable file module, parameter, property, return value, struct, or another attribute.

Information provided by an attribute is also known as metadata. Metadata can be examined at run time by your application to control how your program processes data, or before run time by external tools to control how your application itself is processed or maintained. For example, the .NET Framework predefines and uses attribute types to control run-time behavior, and some programming languages use attribute types to represent language features not directly supported by the .NET Framework common type system.

All attribute types derive directly or indirectly from the Attribute class. Attributes can be applied to any target element; multiple attributes can be applied to the same target element; and attributes can be inherited by an element derived from a target element. Use the AttributeTargets class to specify the target element to which the attribute is applied.

The Attribute class provides convenient methods to retrieve and test custom attributes. For more information about using attributes, see Applying Attributes and Extending Metadata Using Attributes.

简单翻译如下:

Attribute类可以把目标元素和一个预定义的信息或者是用户自定义信息关联起来。这里的目标元素可以是assembly,class,constructor,delegate,enum,event,field,interface,method,可执行文件模块,parameter,property,return value,struct或其它的Attribute。
Attribute提供的信息也被称为元数据(metadata)。元数据能用于在运行时控制怎样访问你的程序数据,或者在运行前通过额外的工具来控制怎样处理你的程序或部署它。例如.NET Framework预定义并使用attribute去控制运行时行为,一些编程语言使用attribute类型来描述.NET Framework中通用类型不直接支持的语言特性。
所有的Attribute类型直接或间接从Attribute类继承。Attribute能应用到任何target元素;多个Attribute能应用到相同的元素;
Attribute类提供遍历的方法去取出和测试自定义Attribute。更多关于Attribute的信息,可以看Applying Attributes和Extending Metadata Using Attributes。

unity中的预定义attribute

看了上述说明,我们可能还不是很清楚attribute到底怎么用,我们先来看看Unity中常用的预定义attribute是怎么使用的,然后再学习怎么使用我们自己自定义的attribute。

DllImport

DllImport应用于方法,用于告诉运行时该方法位于指定的dll的非托管代码中(如c/c++,oc等),如果dll是托管代码生成的(如c#代码生成的dll),则不需要应用此特性。例如,当我们需要调用iOS中的浏览器打开一个url时,可以先编写oc的方法,然后放在项目的plugin目录中,并且在c#脚本中应用DllImport就可以调用了。

oc代码:

复制代码

NSString* CreateNSString (const char* string)
{
    if (string)
        return [NSString stringWithUTF8String: string];
    else
        return [NSString stringWithUTF8String: ""];
}

extern "C" {
    void OpenUrl(const char* urlString)
    {  
        //打开浏览器
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:CreateNSString(urlString)]]; 
        return; 
    } 
}

复制代码

c#代码:

[DllImport("__Internal")]
public static extern string OpenUrl(string url);

用自定义Attribute将枚举和一个描述文本绑定在一起

using UnityEngine;
using System.Collections;
using System;
using System.Collections.Generic;

//属性绑定信息描述
[System.AttributeUsage(System.AttributeTargets.Field | System.AttributeTargets.Enum|System.AttributeTargets.Struct)]
public class EnumPropertiesDesc : System.Attribute
{
    string desc;
    public EnumPropertiesDesc(string str)
    {
        desc = str;
    }
    public string Desc
    {
        get
        {
            return desc;
        }
    }
}
public class EnumPropertiesUtils
{
    static Dictionary<Type, Dictionary<string, string>> cache = new Dictionary<Type, Dictionary<string, string>>();
    public static string GetPropertiesUtils(object o)
    {
        var type = o.GetType();
        Debug.Log("PropertiesUtils_type:" + type);
        if(!cache.ContainsKey(type))
        {
            Cache(type);
        }
        var fieldNameToDesc = cache[type];
        var fieldName = o.ToString();
        Debug.Log("fieldName:" + fieldName);
        return fieldNameToDesc.ContainsKey(fieldName) ? fieldNameToDesc[fieldName] : string.Format("Can not found such desc for field `{0}` in type `{1}`", fieldName, type.Name);
    }
    static void Cache(Type type)
    {
        var dict = new Dictionary<string, string>();
        cache.Add(type, dict);
        var fields = type.GetFields();
        foreach(var field in fields)
        {
            var objs = field.GetCustomAttributes(typeof(EnumPropertiesDesc), true);
            if(objs.Length>0)
            {
                dict.Add(field.Name, ((EnumPropertiesDesc)objs[0]).Desc);
            }
        }
    }
}
public enum EnumTest
{
    [EnumPropertiesDesc("枚举A")]
    Test1,
    [EnumPropertiesDesc("枚举B")]
    Test2
}
public class ClassTest:MonoBehaviour
{
    EnumTest enumTest;
    public void Start()
    {
        enumTest = EnumTest.Test2;
        Debug.Log(string.Format("属性绑定信息测试:{0}", 
            EnumPropertiesUtils.GetPropertiesUtils(enumTest)));

    }
}

猜你喜欢

转载自blog.csdn.net/u014732824/article/details/82789229