C#--反射温习

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq826364410/article/details/81947842

    反射是程序可以访问、检测、修改它本身状态或行为一种能力。
    程序集包括模块,模块包括类型,类型又包括成员。反射可以提供封装程序集、模块和类型的对象。
    反射可以动态的创建类型的实例,把类型绑定在现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。

代码是在Unity中实现的,其实,在纯C#环境中,只要把Start方法中的代码放入Main方法中即可。

using UnityEngine;
using System;
using System.Reflection;

public class Reflection : MonoBehaviour
{
    //反射是程序可以访问、检测、修改它本身状态或行为一种能力。
    //程序集包括模块,模块包括类型,类型又包括成员。反射可以提供封装程序集、模块和类型的对象。
    //反射可以动态的创建类型的实例,把类型绑定在现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。
    void Start()
    {
        //我们的代码运行在"运行时"为我们创建的AppDomain中
        //GetAssemblies获取已加载到应用程序域的程序集。
        Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
        foreach (Assembly assembly in assemblies)
        {
            Type[] types = assembly.GetTypes();
            foreach (Type type in types)
            {
                var customAttribute = type.GetCustomAttributes(typeof(ConvertToBinary), true);
                foreach (var item in customAttribute)
                {
                    var customClass = item as ConvertToBinary;
                    if (customClass == null)
                    {
                        continue;
                    }
                    Type typeC = customClass.m_Type;
                    string methodName = customClass.m_MethodName;
                    if (typeC == null)
                    {
                        Debug.Log("类型为空");
                        continue;
                    }
                    if (string.IsNullOrEmpty(methodName))
                    {
                        Debug.Log(typeC.Name + "方法名为空");
                    }
                    //动态创建类型的实例
                    var typeInstance = Activator.CreateInstance(typeC);
                    var methodInfo = typeC.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Public
                        | BindingFlags.Instance | BindingFlags.InvokeMethod);
                    if (typeInstance != null)
                    {
                        if(methodInfo != null)
                        {
                            methodInfo.Invoke(typeInstance, null);
                        }
                    }
                }
            }
        }
    }
}

 创建一个预定义的特性类ConvertToBinary :

using System;

//特性:描述运行时传递程序中的各种元素(类、方法、结构体等)行为信息的声明性标签
//一个特性,是放置在它应用元素的前面的方括号来描述的
//预定义特性,AttributeUsage是来描述如何使用一个预定义特性类,第一个参数表示可以使用的语言元素,第二个参数表示多用的
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class ConvertToBinary : Attribute
{
    public Type m_Type;
    public string m_MethodName;

    public ConvertToBinary(Type type, string methodName)
    {
        m_Type = type;
        m_MethodName = methodName;
    }
}

给多个class元素应用特性:

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

[ConvertToBinary(typeof(SuitName), "Test1")]
public class SuitName
{
    public List<int> nameList = new List<int>();
    public string id;
    public int num;

    public void Test1()
    {
        Debug.Log("Test1");
    }
}

[ConvertToBinary(typeof(UnityTest), "Test2")]
public class UnityTest
{
    public List<int> list = new List<int>();
    public string id;
    public int num;

    public void Test2()
    {
        Debug.Log("Test2");
    }
}

输出结果,两个测试方法被调用: 

猜你喜欢

转载自blog.csdn.net/qq826364410/article/details/81947842