• C#反射机制详解


    反射的定义:审查元数据并收集关於它的类型信息的能力,元数据(编辑后的基本数据单元)就是一大堆表,编译器会创建一个类定义表,一个字段定义表,一个方法定义表等,System.Reflection命名空间包含的几个类,允许你反射(解析)这些元数据的代码

    一、反射的作用:
    动态的创建类型的实例,将类型邦定到现有对象,或从现有对象中获取类型 
    应用程序需要在运行时从某个特定的程序集中载入一个特定的类型,以便实现某个任务时可以用到反射 
    反射主要应用於类库,这些类库需要知道一个类型的定义,以便提供更多的功能

    二、应用要点:
    现实应用程序中很少使用到反射 
    使用反射动态邦定需要牺牲性能 
    有些元数据信息是不能通过反射获取的 
    某些反射类型是专门為那些CLR开发编辑器开发使用的,所以你要意思到不是所有反射类型都是可以使用的

    三、取得Assembly的方法:
    Assembly.Load 
    Assembly.LoadFile 
    Assembly.LoadFrom 
    Type对象的Assembly方法

    四、反射的成员:
    MemberInfo-成员 
    ConstructorInfo-结构 
    FieldInfo-字段 
    MethodInfo-方法 
    PropertyInfo-属性 
    EventInfo-事件

    五、根据反射取得对象的Member信息
    private void WriteReflectionInfo()
    {
    Type testType = typeof(Test);
    Assembly assembly = testType.Assembly;
    Response.Write("Assembly:" + assembly.FullName + "<br/>");
    Type[] typeList = assembly.GetTypes();   // 获取类型
    // 针对每个类型获取详细信息
    foreach (Type type in typeList)
    {
        Response.Write("------------------------" + type.Namespace + type.Name + "------------------------<br/>");
        // 获得类型的结构信息
        ConstructorInfo[] constructs = type.GetConstructors();

        // 获得类型的字段信息
        FieldInfo[] fields = type.GetFields();
        Response.Write("<b>类的公共字段信息如下:</b>" + "<br/>");
        int a1 = 1;
        foreach (FieldInfo field in fields)
        {
            Response.Write((a1++).ToString() + ". " + field.Name + "<br/>");
        }

        // 获得方法信息
        MethodInfo[] methods = type.GetMethods();

        Response.Write("<b>类的公共方法如下:</b>" + "<br/>");
        int a2 = 1;
        foreach (MethodInfo method in methods)
        {
            ParameterInfo[] parameters = method.GetParameters();
            ParameterInfo reparam = method.ReturnParameter;
            Response.Write((a2++).ToString() + ". " + reparam.ParameterType.Name + " " + method.Name + "(");
            int index = 0;
            foreach (ParameterInfo para in parameters)
            {
                if (index++ < parameters.Length - 1)
                    Response.Write(para.ParameterType.Name + " " + para.Name + ",");
                else
                    Response.Write(para.ParameterType.Name + " " + para.Name);
            }
            Response.Write(")<br/>");
        }

        // 获得属性的信息
        PropertyInfo[] propertys = type.GetProperties();

        Response.Write("<b>类的公共属性如下:</b>" + "<br/>");
        int a3 = 1;
        foreach (PropertyInfo pro in propertys)
        {
            Response.Write((a3++).ToString() + ". " + pro.PropertyType.Name + " " + pro.Name + "{");
            if (pro.CanRead) Response.Write("get;");
            if (pro.CanWrite) Response.Write("set;");
            Response.Write("}<br/>");
        }
        // 获得事件信息
        EventInfo[] events = type.GetEvents();

        Response.Write("<b>类的成员如下:</b>" + "<br/>");
        // 获得成员
        int a4 = 1;
        foreach (MemberInfo mi in type.GetMembers())
        {
            Response.Write((a4++).ToString() + ". " + mi.MemberType.ToString() + " : " + mi.Name + "<br/>");
        }
    }

    六、动态创建对象
    Assembly对象的 CreateInstance方法 
    Activator. CreateInstance方法 
    Type对象的 InvokeMember方法
    // 使用Assembly的CreateInstance方法来取得对象的实例
    private void Assembly_CreateInstance()
    {
        string assemblyName = "SqlModel";
        string className = assemblyName + ".Member";
        // 创建无参数实例
        IDAL.IMember member = (IDAL.IMember)Assembly.Load(assemblyName).CreateInstance(className);
        Response.Write("创建无参数实例:" + member.ID + "<br/>");
        // 创建有参数实例
        Object[] parameters = new Object[1];
        parameters[0] = 10000;
        IDAL.IMember member1 = (IDAL.IMember)Assembly.Load(assemblyName).CreateInstance(className, false, BindingFlags.Default, null, parameters, null, null);
        Response.Write("创建有参数实例:" + member1.ID + "<br/>");
    }

    // 使用Activator的CreateInstance方法来取得对象的实例
    private void Activator_CreateInstance()
    {
        string assemblyName = "SqlModel";
        string className = assemblyName + ".Member";
        // 创建无参数实例
        System.Runtime.Remoting.ObjectHandle obj = Activator.CreateInstance(assemblyName, className);
        IDAL.IMember member = (IDAL.IMember)obj.Unwrap();
        Response.Write("创建无参数实例:" + member.ID + "<br/>");
        // 创建有参数实例
        Object[] parameters = new Object[1];
        parameters[0] = 10000;
        System.Runtime.Remoting.ObjectHandle obj1 = Activator.CreateInstance(assemblyName, className, false, BindingFlags.CreateInstance, null, parameters, null, null, null);
        IDAL.IMember member1 = (IDAL.IMember)obj1.Unwrap();
        Response.Write("创建有参数实例:" + member1.ID + "<br/>");
    }

    // 使用Type的InvokeMember方法来取得对象的实例
    private void Type_InvokeMember()
    {
        string assemblyName = "SqlModel";
        string className = assemblyName + ".Member";
        Assembly assem = Assembly.Load(assemblyName);
        Type type = assem.GetType(className);   // 註意这里如果使用Type.GetType来取得Type的话,那麼assemblyName指定的类一定要是强命名的
        // 创建无参数实例
        IDAL.IMember member = (IDAL.IMember)type.InvokeMember(className, BindingFlags.CreateInstance, null, null, null);
        Response.Write("创建无参数实例:" + member.ID + "<br/>");
        // 创建有参数实例
        Object[] parameters = new Object[1];
        parameters[0] = 10000;
        IDAL.IMember member1 = (IDAL.IMember)type.InvokeMember(className, BindingFlags.CreateInstance, null, null, parameters);
        Response.Write("创建有参数实例:" + member1.ID + "<br/>");
    }

    七、动态调用对象方法

    Type对象的 InvokeMember方法 
    MethodInfo对象的Invoke方法
    // Type对象的 InvokeMember方法来动态调用方法
    private void InvokeMember()
    {
        string assemblyName = "SqlModel";
        string className = assemblyName + ".Member";
        string methodName = String.Empty;
        string result = String.Empty;
        Assembly assem = Assembly.Load(assemblyName);
        Object obj = assem.CreateInstance(className);
        Type type = assem.GetType(className);   // 註意这里如果使用Type.GetType来取得Type的话,那麼assemblyName指定的类一定要是强命名的
        // 动态调用无参数的方法
        methodName = "GetName";
        result = (string)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, null);
        Response.Write(methodName + "方法的返回值:" + result + "<br/>");
        // 动态调用有参数的方法
        methodName = "Update";
        Object[] methodParams = new Object[1];
        methodParams[0] = DateTime.Now;
        result = (string)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, methodParams);
        Response.Write(methodName + "方法的返回值:" + result + "<br/>");
        // 动态调用参数构架函数的带有参数的方法
        Object[] parameters = new Object[1];
        parameters[0] = 10000;
        obj = assem.CreateInstance(className,false,BindingFlags.CreateInstance, null, parameters, null, null);
        result = (string)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, methodParams);
        Response.Write(methodName + "方法的返回值:" + result + "<br/>");
    }

    // MethodInfo对象的Invoke方法来动态调用方法

    private void MethodInfo_Invoke()
    {
        string assemblyName = "SqlModel";
        string className = assemblyName + ".Member";
        string methodName = String.Empty;
        string result = String.Empty;

        Assembly assem = Assembly.Load(assemblyName);
        Object obj = assem.CreateInstance(className);
        Type type = assem.GetType(className);   // 註意这里如果使用Type.GetType来取得Type的话,那麼assemblyName指定的类一定要是强命名的
        // 动态调用无参数的方法
        methodName = "GetName";
        MethodInfo methodInfo = type.GetMethod(methodName);
        result = (string)methodInfo.Invoke(obj, null);
        Response.Write(methodName + "方法的返回值:" + result + "<br/>");
        // 动态调用有参数的方法
        methodName = "Update";
        Object[] methodParams = new Object[1];
        methodParams[0] = DateTime.Now;
        MethodInfo method = type.GetMethod(methodName);
        result = (string)method.Invoke(obj, methodParams);
        Response.Write(methodName + "方法的返回值:" + result + "<br/>");
    }

    --------------------------------------------------------------------------------
    以上所使用的SqlModel.Member為:
    新建一个SqlModel类库,在其下建立一个Member的类

    namespace SqlModel
    {
        public class Member : IDAL.IMember
        {
            private int _id = 100;
            public int ID
            {
                get { return _id; }
                set { _id = value; }
            }
            private string _name = "limin";
            public string Name
            {
                get { return _name; }
                set { _name = value; }
            }

            public Member() { }
            public Member(int id)
            {
                _id = id;
            }

            private void Init()
            { }

            public string GetName()
            {
                return _name;
            }
            public string Update (DateTime cdate)
            {
                return "{" + String.Format("ID:{0},Name:{1},CreateDate:{2}",_id,_name,cdate) + "}";
            }
        }
    }

    复制代码
  • 相关阅读:
    英文句子相似性判断
    机器学习(一)特征工程基本流程
    经典卷积神经网络(LeNet、AlexNet、VGG、GoogleNet、ResNet)的实现(MXNet版本)
    Google免费GPU使用教程(亲测可用)
    XGBoost、LightGBM的详细对比介绍
    终身机器学习:一种可持续学习的范式
    机器学习中安全与隐私问题(对抗性攻击)
    频繁模式挖掘中Apriori、FP-Growth和Eclat算法的实现和对比(Python实现)
    Webpack教程,更新中
    @babel/plugin-transform-runtime
  • 原文地址:https://www.cnblogs.com/tsql/p/8676787.html
Copyright © 2020-2023  润新知