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运算符,这个运算符的参数是类型的名称,但不放在引号中:
Type t =typeof(double);
- 使用GetType()方法,所以类都会从System.Object继承这个方法:
double d =10;Type t = d.GetType();
在一个变量上调用GetType()方法,返回的Type对象只与该数据类型相关,不包含该类型实例的任何信息。
- 调用Type类的静态方法GetType():
Type t =Type.GetType("System.Double");
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(“类型全名”);
适合于类型的名称已知
方式二:
obj.GetType();
适合于类型名未知,类型未知,存在已有对象
方式三:
typeof(类型)
适合于已知类型
方式四:
Assembly.Load(“XXX”).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#反射的实现原理及简单应用相关推荐
- java反射机制的原理与简单使用
一. 原理 简单的来说,反射机制其实就是指程序在运行的时候能够获取自身的信息.如果知道一个类的名称/或者它的一个实例对象, 就能把这个类的所有方法和变量的信息(方法名,变量名,方法,修饰符,类型,方法 ...
- go interface 转int_大神是如何学习 Go 语言之反射的实现原理
反射是 Go 语言比较重要的一个特性之一,虽然在大多数的应用和服务中并不常见,但是很多框架都依赖 Go 语言的反射机制实现一些动态的功能.作为一门静态语言,Golang 在设计上都非常简洁,所以在语法 ...
- Java注解的基本概念和原理及其简单实用
一.注解的基本概念和原理及其简单实用 注解(Annotation)提供了一种安全的类似注释的机制,为我们在代码中添加信息提供了一种形式化得方法,使我们可以在稍后某个时刻方便的使用这些数据(通过解析 ...
- Java反射及 IoC原理、内省机制
JAVA反射及IoC原理.JAVA内省 1. 反射 反射是框架设计的灵魂,使用前提:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码文件). 1.1 反射概述 主要指程 ...
- Java 数据交换格式反射机制SpringIOC原理分析
数据交换格式&反射机制&SpringIOC原理分析 什么是数据交换格式? 数据交换格式使用场景 JSON简单使用 什么是JSON? JSON格式的分类 常用JSON解析框架 使用fas ...
- 【2021软件创新实验室暑假集训】SpringMVC框架(设计原理、简单使用、源码探究)
系列文章目录 20级 Java篇 [2021软件创新实验室暑假集训]计算机的起源与大致原理 [2021软件创新实验室暑假集训]Java基础(一) [2021软件创新实验室暑假集训]Java基础(二) ...
- java 内省机制_Java反射及 IoC原理、内省机制
JAVA反射及IoC原理.JAVA内省 1. 反射反射是框架设计的灵魂,使用前提:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码文件). 1.1 反射概述主要指程序可 ...
- 彻底搞懂java反射技术及其原理
概述:反射是java中最强大的技术之一,很多高级框架都用到了反射技术,面试中也是经常问的点,所以搞懂反射非常重要! 文章目录 1.反射是什么? 2.反射的底层原理 3.三种方式获取Class对象 4. ...
- python装饰器实例-Python装饰器原理与简单用法实例分析
本文实例讲述了Python装饰器原理与简单用法.分享给大家供大家参考,具体如下: 今天整理装饰器,内嵌的装饰器.让装饰器带参数等多种形式,非常复杂,让人头疼不已.但是突然间发现了装饰器的奥秘,原来如此 ...
最新文章
- JGG:华中师大蒋兴鹏组-不同稀疏水平信号的微生物组关联检验方法
- jsr223 java_JSR223 Java使用脚本引擎动态修改业务逻辑
- 程序员们,今天就让她陪你们放松一下吧。她还有大宝剑哦。【原创】
- lede旁路由作用_关于电容的旁路与去偶总结
- 计算机无法同步时间,为什么在Win7中无法同步计算机时间?
- jqgrid 编辑列拿不到值_如何在DAX Stadio和Excel中返回表和度量值?
- C#编写WINNT服务,随便解决安卓开发遇到的5037被众多程序无节操占用的问题
- 如何调换antd中Modal对话框确认按钮和取消按钮两个按钮的位置
- bzoj 1605: [Usaco2008 Open]Crisis on the Farm 牧场危机(DP)
- Petri net是什么
- MFC CListCtrl 将一个列表的选中项添加到另一个列表
- 某验四代消消乐 js逆向
- SQL Server 添加Northwind数据库
- 卡内基梅隆计算机专业,卡内基梅隆大学计算机专业介绍
- 逃离北京回家创业--团队组建篇
- 爬虫2_起点中文网字体反爬
- 视频压缩原理之 预测编码
- 人脑认知计算模型简介(上)
- 机器学习入门(二) 准备工作
- 搜狗输入法更换字体与皮肤