1. 程式人生 > >Unity C#基礎:反射

Unity C#基礎:反射

路還很遠,雖然望不到邊,但至少一步一個腳印

目錄

1.什麼是反射?

是指程式訪問,檢測和修改它本身狀態的一種機制,還可以動態建立例項並執行其中的方法。

2.發射的用途:

類 型 作用
Assembly 定義和載入程式集,載入程式集清單中列出的模組,以及從此程式集中查詢型別並建立該型別的例項。
Module 瞭解包含模組的程式集以及模組中的類等,還可以獲取在模組上定義的所有全域性方法或其他特定的非全域性方法。
ConstructorInfo 瞭解構造器的名稱,引數,訪問修飾符(如public或private)和實現詳細資訊(如abstract或virtual)等。使用Type的GetConstructors或GetConstructor方法來呼叫特定的建構函式。
MethodInfo 瞭解方法的名稱,返回型別,引數,訪問修飾符(如public或private)和實現詳細資訊(如abstract或virtual)等。使用type的GetMethods或GetMethod方法來呼叫特定的方法。
FieldInfo 瞭解欄位的名稱,方法修飾符(如public或private)和實現詳細資訊(如static)等,並獲取或設定欄位值。
EventInfo 瞭解事件的名稱,事件處理程式資料型別,自定義特性,宣告型別或反射型別等,並新增或移除事件處理程式。
PropertyInfo 瞭解屬性的名稱,資料型別,宣告型別,反射型別和只讀或可寫狀態等,並獲取或設定屬性值。
ParameterInfo 瞭解引數的名稱,資料型別,引數是輸入引數還是輸出引數等,以及引數在方法簽名中的位置等。

3.反射的用法例項:

1.獲取程式集資訊和型別資訊。

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

public class SelectReflectionDemo : MonoBehaviour
{
    public void Method()
    {

    }
    public
void Notify() { } public int Count; public int Max; private string mName; private int mLevel; public string Name { get { return mName; } set { Name = value; } } public int Level { get { return mLevel; } set { mLevel = value; } } void Start() { List<string> ScrInfos = new List<string>(); Type my = this.GetType(); ScrInfos.Add(my.Name);//類名 ScrInfos.Add(my.Namespace);//所屬名稱空間 ScrInfos.Add(my.Assembly.ToString());//程式集資訊 FieldInfo[] fieinfos = my.GetFields();//獲取欄位集合(public) foreach (FieldInfo info in fieinfos) { ScrInfos.Add(info.ToString()); } PropertyInfo[] proinfos = my.GetProperties();//獲取屬性集合(public) for (int i = 0; i < 2; i++) { ScrInfos.Add(proinfos[i].ToString()); } MethodInfo[] methinfos = my.GetMethods();//獲取所有的方法 for (int i = 0; i < 2; i++) { ScrInfos.Add(methinfos[i].ToString()); } foreach (string str in ScrInfos) { Debug.Log(str); } } }

2.動態建立型別例項並執行其中的方法。

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

public class CreateReflectionDemo : MonoBehaviour
{

    // Use this for initialization
    void Start()
    {
        //兩種建立方式,一種是根據type型別建立,一種是根據字串建立。
        Type mytype = typeof(MyClass);
        MyClass my = Activator.CreateInstance(mytype) as MyClass;//根據type型別建立
        my.Name = "我是使用type建立的";
        Debug.Log(my.Name);
        //
        string AssemblyName =Assembly.GetExecutingAssembly().GetName().Name;//獲取程式集名稱
        string strNameSpace= System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Namespace;//獲取名稱空間名稱;
        string strClassName =mytype.Name;
        string fullclassName = strNameSpace + "." + strClassName;//類全名(名稱空間.類名稱)
        Debug.Log(AssemblyName);
        Debug.Log(fullclassName);
        //需要程式集字串和類全名字串(名稱空間.類名稱)
        MyClass mys = (MyClass)Assembly.Load(AssemblyName).CreateInstance(fullclassName);
        mys.Name = "我是通過字串建立的";
        Debug.Log(mys.Name);
    }
}
public class  MyClass
{
    public int Count;
    public int Max;
    private string mName;
    private int mLevel;
    public string Name
    {
        get { return mName; }
        set { mName = value; }
    }
    public int Level
    {
        get { return mLevel; }
        set { mLevel = value; }
    }
    public void Method()
    {

    }
    public void Notify()
    {

    }
}

4.反射的缺點:

1.效能問題:使用反射是一種解釋操作,遠慢於直接程式碼。 2.程式更加複雜:使用反射會模糊程式的內部邏輯,發射是繞過原始碼的技術,因而帶來了維護的問題。反射程式碼比相應的直接程式碼更復雜。