c#中的特性,以及一些思考

來源:互聯網
上載者:User

標籤:注釋   tor   本質   特殊   message   對象   bool   執行   目的   

unity中會有像[range(0,1)]這樣的特性寫法,其非常方便的限制了變數範圍但是。我一直很好奇這是怎麼實現的,所以翻了翻其他博主對其的解釋和應用。

 

一,什麼是特性

  有一種解釋我很能接受,特性就像牡蠣附在對象上。其本質也是一種對象,特殊之處在於其編譯時間就存在了,也就是在程式運行之前就存在了。

二,如何定義一個特性

 1 namespace UnityEngine 2 { 3  4     [AttributeUsage(AttributeTargets.Field, Inherited = true, AllowMultiple = false)] 5  6     public abstract class PropertyAttribute : Attribute 7     { 8         protected PropertyAttribute(); 9 10         public int order { get; set; }11     }12 }

只是啥=。= 不就是一個對象嗎,我copy了unity中的一段特性代碼。事實上所有的特性都繼承 Attribute,unity在中多封裝了一層 PropertyAttribute ,且給每個特性加上了一個ID。

所以定義一個特性只需要繼承 Attribute 就可以了。

那麼其上面的特性 AttributeUsage又表示什麼呢,

三,特性的使用

AttributeUsage=。=直接說明了特性的使用範圍嘛,後面標註了幾個屬性
AttributeTargets.Field代表可以附著在欄位上,其他地方不能加不上這個標籤特性。AttributeTargets本身是枚舉值,且其是c#預製的特性變數。
Inherited 是否可以繼承這就很好理解了
AllowMultiple 是否能夠混合使用,也就是一個類上掛倆三個特性。

理解可這些參數之後就可以自己寫一個特性玩玩了,這裡我寫一個自訂的debuginfo在unity中調用
(1)聲明
using System;using UnityEngine;//特性所能使用的範圍[AttributeUsage(AttributeTargets.Method|AttributeTargets.Field    , AllowMultiple =true)]public class DebugerCoderAttribute : UnityEngine.PropertyAttribute{    private string codename;    private string codeLasttime;    private bool Ischeck;    private string message;    public DebugerCoderAttribute(string CoderName, string CodeLastTime, bool Checked)    {        codename = CoderName;        codeLasttime = CodeLastTime;        Ischeck = Checked;        message = "";          }    public DebugerCoderAttribute(string CoderName, string CodeLastTime,string OtherInfo, bool Checked)    {        codename = CoderName;        codeLasttime = CodeLastTime;        Ischeck = Checked;        message = OtherInfo;    }    public string ScriptsCoder    {        get        {            return codename;        }    }    public string ScriptsTime    {        get        {            return codeLasttime;        }    }    public bool ScriptsIsChecked    {        set        {            Ischeck = value;        }        get        {            return Ischeck;        }    }    public string Message    {        set        {               message = value;        }        get        {            return message;        }    }}

  (2)指令碼調用

public class TempReadJobScrpts : MonoBehaviour {    [DebugerCoder("yang", "1995", false, Message = "只能注釋方法名,在MyinfoDebug中可以修改完成指定位置資訊讀取")]    public void MyMethod()    {    }}

(3)反射調用(更好點可以寫到editor中運行達到自行檢測運行指令碼方法順序的目的)

/*此類可以寫在editor中運行達到自運行檢測的目的*/public class MyInfoDebuger : MonoBehaviour {    public GameObject SelectObj;    /*目前只能讀取指令碼為 SelectObj中 TempReadJobScrpts的注釋資訊*/    public readonly string TempReadJobScrpts= "TempReadJobScrpts";    public bool IsReadBug = true;    public bool ShowAllMehodOfScripts = false;    // Use this for initialization    void Start () {        if (IsReadBug)         ShowDebugInfo();    }    void GetAllMyPrivareScripts()    {        //擷取所有自訂指令碼的名字    }    public void ShowDebugInfo()    {//這裡需要修改成擷取所有指令碼的資訊參數        try        {            //僅在unity 中需要使用  此處非自執行。。便利指令碼效率比較低            //當方法加入public時 此處可以擷取            MonoBehaviour[] monos = SelectObj.GetComponents<MonoBehaviour>();            foreach (var item in monos)            {                if (item.GetType().ToString().EndsWith(TempReadJobScrpts))                {                    Debug.Log("is reading>>:" + ((MonoBehaviour)item).GetType());                    //顯示有標籤的方法 此處只能用在方法上    此處設定的是私人和共有方法                    MethodInfo[] meths = ((MonoBehaviour)item).GetType().GetMethods(BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.Public);                    foreach (MethodInfo met in meths)                    {                                                if (Attribute.GetCustomAttributes(met).Length>0)                        {                            if (ShowAllMehodOfScripts)                                Debug.Log(met.Name);                            Attribute[] attris = Attribute.GetCustomAttributes(met);                                                     foreach (Attribute at in attris)                            {                                if (at.GetType() == typeof(DebugerCoderAttribute))                                {                                    DebugerCoderAttribute info = (DebugerCoderAttribute)at;                                    Debug.Log("coder:" + info.ScriptsCoder + ","                                        + " message:" + info.Message+" date:"+info.ScriptsTime);                                }                            }                        }                    }                }            }        }        catch (System.Exception ex)        {            Debug.Log(this.name+" "+ ex.ToString());        }    }}

 運行結構:

 

c#中的特性,以及一些思考

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.