目录
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\n
Copyright © 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 TODO
public 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;
//计时器id
private 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
{
//提示UI
public const string Tip_UI = "Tip_UI";
}