反射学习笔记(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.源码
posted @ 2010-08-21 12:35  clound  阅读(606)  评论(0编辑  收藏  举报