C#反射的实现原理及简单应用
目錄
一、System.Type類
二、Assembly類
?三、常用類
一、取得數據類型Type常用方式:
二、MethodInfo(方法)
三、PropertyInfo(屬性)
四、FieldInfo(字段)
五、ConstructInfo(構造方法)
四、動態創建對象
五、簡單應用,例:一個簡單的UIManager Demo
C#反射技術主要基于System.Type類和System.Reflection.Assemble類,通過Type類可以訪問關于任何數據類型的信息,Assemble類用于訪問給定程序集的相關信息,或把這個程序集,?加載到程序中。
一、System.Type類
?Type類是一個抽象類。只要實例化了一個Type對象,實際上就實例化了Type的一個派生類。盡管一般情況下派生類只提供各種Type方法和屬性的不同重載,但是這些方法和屬性返回對應數據類型的正確數據,Type有與每種數據類型對應的派生類。它們一般不添加新的方法或屬性
通常,獲取Type有三種常用方式:
- 使用typeof運算符,這個運算符的參數是類型的名稱,但不放在引號中:
- 使用GetType()方法,所以類都會從System.Object繼承這個方法:
在一個變量上調用GetType()方法,返回的Type對象只與該數據類型相關,不包含該類型實例的任何信息。
- 調用Type類的靜態方法GetType():
Type是很多反射功能的入口,它實現很多方法和屬性,可用的屬性都是只讀的:可以使用Type確定數據的類型,但不能使用它修改該類型。
二、Assembly類
?Assembly類允許訪問給定程序集的元數據,它也包含可以加載和執行程序集(假定該程序集是可執行的)的方法。與Type類一樣,Assembly類包含非常多的方法和屬性。
| 命名空間 | 描述 |
| System.Reflection.Assembly? | 程序集 |
| System.Reflection.MemberInfo | 成員信息 |
| System.Reflection.EventInfo | 事件 |
| System.Reflection.FieldInfo | 字段 |
| System.Reflection.MethodBase | 基類方法 |
| System.Reflection.ConstructorInfo | 構造函數 |
| System.Reflection.MethodInfo | 方法 |
| System.Reflection.PropertyInfo | 屬性 |
| System.Type | 類、對象的類型對象 |
?三、常用類
一、取得數據類型Type常用方式:
方式一:
Type.GetType(“類型全名”);適合于類型的名稱已知
方式二:
適合于類型名未知,類型未知,存在已有對象
方式三:
適合于已知類型
方式四:
適合于類型在另一個程序集中?
二、MethodInfo(方法)
重要方法: Invoke?三、PropertyInfo(屬性)
重要方法:SetValue GetValue四、FieldInfo(字段)
?重要方法:SetValue GetValue五、ConstructInfo(構造方法)
重要方法:Invoke四、動態創建對象
Activator.CreateInstance(string 程序集名稱,string 類型全名) Activator.CreateInstance(Type type);Assembly assembly = Assembly.Load(程序集); assembly.CreateInstance(Type);//找到有參構造方法,動態調用構造方法 type.GetConstructor(typeof(string)).Invoke()五、簡單應用,例:一個簡單的UIManager Demo
?此UIManager適用于UI不繼承MonoBehaviour,用反射獲取程序集,動態創建UI實例!
/*----------------------------------------------------------------Created by 王銀文件名: UIManager創建時間: 2022.5.9文件功能描述: UIManager //去除空行的正則表達式 (?<=\r\n)\r\nCopyright ? 2022年 王銀 All rights reserved. ----------------------------------------------------------------*/ using UnityEngine; using System.Collections.Generic; public enum UILayer {//場景層Scene,//普通全屏UI層,默認互斥(打開這個就關閉比其他的)Default,//全屏UI的二級彈窗Secondary,//默認的彈窗Pupop,//新手引導層Guide,//斷線重連、系統提示等TipAndWraning } public class UIManager {public static readonly UIManager Instance = new UIManager();private Dictionary<UILayer, Transform> layerPanelDic;private Dictionary<string, View> viewDic;private List<string> showList;private List<string> linkList;private string nowView;public string crtSelectView = "";public static Camera UICamera { get; private set; }public static GameObject Canvas { get; private set; }public UIManager(){if (Application.isPlaying){Canvas = GameObject.FindWithTag("Canvas");layerPanelDic = new Dictionary<UILayer, Transform>();viewDic = new Dictionary<string, View>();showList = new List<string>();linkList = new List<string>(10);UICamera = GameObject.FindWithTag("UICamera").GetComponent<Camera>();InitChildPanel();}}private void InitChildPanel(){for (int i = 0; i < 6; i++){GameObject panelGO = new GameObject();UILayer layer = (UILayer)i;panelGO.name = layer.ToString();panelGO.transform.SetParent(Canvas.transform);panelGO.transform.localPosition = Vector3.zero;panelGO.transform.localScale = Vector3.one;layerPanelDic.Add(layer, panelGO.transform);}}public void ShowView<T>(string name, params object[] data) where T : View{ShowView(name, data);}public void ShowView(string name, params object[] data){if (IsShowView(name)) return;View view;if (!viewDic.TryGetValue(name, out view)){view = CreateView(System.Type.GetType(name), name);}if (view != null){if (view.Layer == UILayer.Default){if (nowView != name){HideOtherView(name);nowView = name;}}if (showList.IndexOf(name) == -1){showList.Add(name);}linkList.Add(name);view.Showing(data);}}//谷歌要求按手機實體返回鍵調用此處 linkList TODOpublic void Back(){if (linkList.Count > 1){View view;int index = linkList.Count - 1;string viewName = linkList[index - 1];string viewNameTemp = linkList[index];linkList.RemoveAt(index);nowView = "";if (viewDic.TryGetValue(viewName, out view)){if (view != null){HideView(viewNameTemp);ShowView(viewName);}}else{viewName = string.IsNullOrEmpty(crtSelectView) ? viewName : crtSelectView;HideView(viewNameTemp);ShowView(viewName);}}}public void RemoveLinkContentByName(string name){for (int index = 1; index < linkList.Count; index++){if (linkList[index].Contains(name)){linkList.RemoveAt(index);}}}public void HideView<T>(string name) where T : View{HideView(name);}public void HideView(string name){View view;string showName;int len = showList.Count;if (len > 0){for (int i = 0; i < len; i++){showName = showList[i];if (showName == name){if (viewDic.TryGetValue(showName, out view)){showList.RemoveAt(i);view.Hiding();break;}}}}}public void HideOtherView(string name){View view;string showName;int len = showList.Count;for (int i = 0; i < len;){if (showList.Count == 0)break;showName = showList[i];if (showName != name){if (viewDic.TryGetValue(showName, out view)){if (view.Layer != UILayer.TipAndWraning){showList.RemoveAt(i);len--;view.Hiding();continue;}}}i++;}}public void HideAllView(){View view;string showName;int len = showList.Count;for (int i = 0; i < len;){showName = showList[i];if (viewDic.TryGetValue(showName, out view)){showList.RemoveAt(i);len--;view.Hiding();continue;}i++;}}public void DestroyView(string name){View view;if (viewDic.TryGetValue(name, out view)){if (showList.Remove(name)){view.Hiding();}view.Destroy();viewDic.Remove(name);}Resources.UnloadUnusedAssets();System.GC.Collect();}public void DestroyAllView(){foreach (KeyValuePair<string, View> item in viewDic){if (showList.Remove(item.Key)){item.Value.Hiding();}item.Value.Destroy();}viewDic.Clear();Resources.UnloadUnusedAssets();System.GC.Collect();}public bool IsShowView(string name){return showList.IndexOf(name) >= 0;}private View CreateView(System.Type type, string prefabID){UIAttribute classAttribute = (UIAttribute)System.Attribute.GetCustomAttribute(type, typeof(UIAttribute));GameObject prefab = InstantiatePrefab(prefabID, classAttribute.Layer);View view = null;if (prefab != null){view = System.Activator.CreateInstance(type) as View;view.Activation(prefab);view.Layer = classAttribute.Layer;view.IsFull = classAttribute.IsFull;viewDic.Add(prefabID, view);}return view;}private GameObject InstantiatePrefab(string prefabID, UILayer layer){GameObject prefab = null;Object obj = null;if (obj == null){string prefabPath = "Prefabs/UI/" + prefabID;obj = Resources.Load(prefabPath);}if (obj != null){prefab = GameObject.Instantiate(obj) as GameObject;prefab.name = prefabID;Transform parent;if (!layerPanelDic.TryGetValue(layer, out parent)){parent.SetParent(Canvas.transform);//WY}prefab.transform.SetParent(parent);prefab.transform.localScale = Vector3.one;prefab.transform.localPosition = Vector3.zero;}return prefab;} }設計接口:
using UnityEngine; public interface IView {void Activation(GameObject go);void Showing(params object[] data);void Hiding();void Destroy(); }實現接口:
using UnityEngine; using System.Collections.Generic; public class View : IView {protected GameObject mUIPrefab;protected Transform mTransform;public UILayer Layer { get; set; }public bool IsFull { get; set; }private Dictionary<System.Type, object> mBehaviours = new Dictionary<System.Type, object>();public View(){}public void Activation(GameObject go){mUIPrefab = go;mTransform = go.transform;Start();//UGUI中可以省略此UI適配Adaptive();}protected virtual void Start(){}protected virtual void Adaptive(){}protected virtual void Enable(params object[] data){}protected virtual void Dormancy(){}public virtual void Back(){}public void Showing(params object[] data){if (mUIPrefab != null){mUIPrefab.SetActive(true);Enable(data);}}public void Hiding(){if (mUIPrefab != null){Dormancy();mUIPrefab.SetActive(false);}}public virtual void Destroy(){mTransform = null;if (mUIPrefab != null){GameObject.Destroy(mUIPrefab);mUIPrefab = null;}}protected T GetChild<T>(string childName) where T : MonoBehaviour{T[] childs = null;if (mBehaviours.ContainsKey(typeof(T))){childs = mBehaviours[typeof(T)] as T[];}else{childs = mUIPrefab.GetComponentsInChildren<T>();mBehaviours.Add(typeof(T), childs);}GameObject child = null;foreach (T t in childs){if (childName.Equals(t.name))child = t.gameObject;}if (child != null){return child.GetComponent<T>();}return default(T);}protected GameObject GetChild(string childName){return mTransform.Find(childName).gameObject;}protected Transform FindChild(string childName){return mTransform.Find(childName);} } using System;[AttributeUsage(AttributeTargets.Class)] public class UIAttribute : Attribute {public UILayer Layer { get; set; }public bool IsFull { get; set; } }使用方法:
using System; using UnityEngine.UI;[UI(Layer = UILayer.TipAndWraning, IsFull = true)] public class Tip_UI : View {private Text messageText;private float timer;//計時器idprivate int id;protected override void Start(){base.Start();messageText = GetChild("Image/Text").GetComponent<Text>();}protected override void Enable(params object[] data){base.Enable(data);if (data.Length == 1){string str = (string)data[0];messageText.text = str;}else if (data.Length == 2){string str = (string)data[0];string str1 = (string)data[1];messageText.text = string.Format("{0}{1}", str, str1);}timer = 1.5f;id = TimerManager.instance.Add((int value1) =>{UIManager.Instance.HideView(WindowName.Tip_UI);}, timer, 1);}public override void Back(){base.Back();}protected override void Dormancy(){TimerManager.instance.Remove(id);base.Dormancy();} } public class WindowName {//提示UIpublic const string Tip_UI = "Tip_UI";}總結
以上是生活随笔為你收集整理的C#反射的实现原理及简单应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 两个PDF比较标出差异_PDF最全接触
- 下一篇: C# 枚举高级用法之Descriptio