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\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";

}

  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王 银

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值