• 反射学习笔记(1)


    一直在用反射,可是却没有系统了解。这几天好好看了下Reflection命名空间,做个笔记。

    1.什么叫反射

      我觉得.Net 中的反射 中的总结不错。

    反射是一种宽泛的叫法,它通过 System.Reflection 命名空间 并 配合 System.Type 类,提供了在运行时(Runtime)对于 类型和对象(及其成员)的基本信息 以及 元数据(metadata)的访问能力。

      你也可以这么理解,通过反射我们可以在运行时获得各种信息,如程序集、模块、类型、字段、属性、方法和事件,通过对类型动态实例化后,还可以对其执行操作。简单来说就是用string可以在runtime为所欲为的东西,实际上就是一个.net framework内建的万能工厂。一般用于插件式框架程序和设计模式的实现,当然反射是一种手段可以充分发挥其能量来完成你想做的任何事情(你可以通过反射调用程序集的private,internal等原本无法访问的类或者方法。)

    2.如何使用反射

      实例1: 三层项目中常用到, 工厂通过反射动态加载,实例化出数据层类实例,供业务层调用。

      接口:IAnimal.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    namespace Reftext
    {
        public interface IAnimal
        {
            string Name(string aa);
        }
    }
    实现类:Dog.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    namespace Reftext
    {
       public class Dog:IAnimal
        {
           public string Name(string aa)
           {
               return aa;
           }
        }
    }

    业务层调用方法:

      Reftext.IAnimal animal = (Reftext.IAnimal)Assembly.Load("Reftext").CreateInstance("Reftext.Dog");
      string flag=animal.Name("dog");

    实例2:如果类没有定义相关接口,如何访问public ,private,属性或方法等。

    定义Userinfo类:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    namespace Reftext
    {
        internal class Userinfo
        {
            private string name;
            private int age;
            public Userinfo()
            { 
            }
            private void ChangeName(string NewName)
            {
                name = NewName;
            }
            public void ChangeAge(int NewAge)
            {
                age = NewAge;
            }
            public string WriteInfo(string NewName, int NewAge)
            {
                return "您的信息:" +"姓名"+ NewName +"   年龄"+ NewAge.ToString();
            }
            public void WriteNameOut(string NewName,out string OutName)
            {
                OutName = "Bill " + NewName;
            }
            private string GetString(string str)
            {
                return "一个参数"+str;
            }
            private string GetString(string str1, string str2)
            {
                return "两个参数"+str1 + str2;
            }
            public static string WriteName(string s)
            {
                return "名称为:" + s;
            }
        }
    }
    使用方法:
           Assembly ass = Assembly.Load("Reftext");
            //public方法访问
            object obj = ass.CreateInstance("Reftext.Userinfo");
            var othermethod1 = obj.GetType().GetMethod("ChangeAge");
            othermethod1.Invoke(obj, new object[] { 12 });
            //private 方法访问
            MethodInfo m0 = obj.GetType().GetMethod("ChangeName", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(string) }, null);
            m0.Invoke(obj, new string[] { "111" });
            //静态方法调用
            var othermethodstatic = obj.GetType().GetMethod("WriteName");
            othermethodstatic.Invoke(obj, new object[] { "static" });
            //多个参数
            var othermethod2 = obj.GetType().GetMethod("WriteInfo");
            object flag2=othermethod2.Invoke(obj, new object[] {"夏明",12 });
            //带out 参数
            var othermethod3 = obj.GetType().GetMethod("WriteNameOut");
            object[] invokeArgs3 = new object[] { "worton" ," husiton"};
            othermethod3.Invoke(obj, invokeArgs3);
            object flag3 = invokeArgs3[1];
            //方法重载的调用
            MethodInfo m1 = obj.GetType().GetMethod("GetString", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(string) }, null);
            MethodInfo m2 = obj.GetType().GetMethod("GetString", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(string), typeof(string) }, null);
            m1.Invoke(obj, new string[] { "111" });
            m2.Invoke(obj, new string[] { "111","222" });
     注:Assembly加载程序集有多种方法:
         Assembly.LoadFile  
         Assembly.Load 等 具体用法看看MSDN吧。

    3.利用Type类获取程序集信息

      Reftext.Dog dog= new  Reftext.Dog();
            Type type = dog.GetType();
            Response.Write("类型名:" + type.Name+"</br>");
            Response.Write("类全名:" + type.FullName + "</br>");
            Response.Write("命名空间名:" + type.Namespace + "</br>");
            Response.Write("程序集名:" + type.Assembly + "</br>");
            Response.Write("模块名:" + type.Module + "</br>");
            Response.Write("基类名:" + type.BaseType + "</br>");
            Response.Write("是否类:" + type.IsClass + "</br>");
            Response.Write("类的公共成员:");
            MemberInfo[] memberInfos = type.GetMembers();//得到所有公共成员
            foreach (var item in memberInfos)
            {
              //  Console.WriteLine("{0}:{1}", item.MemberType, item);
                Response.Write(item.MemberType.ToString() +"  "+ item.ToString() +"</br>");
            }

    参考:1.反射----重载的方法

             2..Net 中的反射
           3.实例总结C#反射基础知识[原创]
           4.源码
  • 相关阅读:
    python基础学习(2)
    python基础语法
    面试常见问题(2)——数据库
    面试常见问题(1)——TCP协议
    python基础回顾(一)
    安装Beautiful Soup
    MongoDB的安装、配置和可视化
    神奇的斐波那契---解决兔子繁衍问题
    正规式、正规文法与自动机
    词法分析程序的设计与实现
  • 原文地址:https://www.cnblogs.com/dooom/p/1805255.html
Copyright © 2020-2023  润新知