C#反射机制

最近仔细学习了一下C#的反射机制,希望能和大家分享。 提到反射我想大家都不陌生,反射提供了封装程序集、模块和类型的对象( Type 类型)。可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性,所在命名空间using System.Reflection。

反射的作用:

  1. 1.使用反射可以动态创建类型的实例,然后将实例再邦定到现有的对象或从现有对象中获取类型。
  2. 2.应用程序需要在运行时从某个特定的程序集中载入特定的类型,以创建特定类型的实例。

       正是因为反射的特性(动态创建实例)所以在多个模块之间减少代码的紧偶合方面,利用反射可以起到了很大的改善。但是反射也有它的弊端,就是要以牺牲性能为代价,而且有些信息利用反射是无法得到的。在使用时要根据情况进行选择。我想通过下图的层次模型大家可能会更明白它的机制。

 

以上关于反射知识了解之后,在通过代码大家可能会更好的理解反射:

首先在Vs2008中创建一个类型,命名为ReflectDemo类库。并添加一个名为ReflectTest的类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SKY.ReflectDemo
{
    public class ReflectTest : IPerson
    {
        private string _name;
        private int _age;
        public string Name { get { return this._name; } set { this._name = value; } }
        public int Age { get { return this._age; } set { this._age = value; } }
        public ReflectTest(string name, int age)
        {
            this._name = name;
            this._age = age;
        }
        public string WelcomeInfo(string name)
        {
            return "welcome come here " + name;
        }
        public static string WriteStaticInfo(string name)
        {
            return "welcome come here static" + name;
        }
        public static string WriteStaticNoParam()
        {
            return "Static and No parma";
        }
        public void Show(string info)
        {
            Console.WriteLine(info);
        }
        public ReflectTest() { }
        public string WriteNoPara()
        {
            return "你使用的是无参的方法";
        }
        private string WritePrivate()
        {
            return "私有类型的方法";
        }

        #region IPerson 成员

        public int Add()
        {
            return Age;
        }

        #endregion
    }
    public interface IPerson
    {
        /// <summary>
        /// 添加对象
        /// </summary>
        /// <returns></returns>
        int Add();
    }
}

然后再创建一个客户端程序:例如clientTestDemo,添加刚刚新建的程序集引用,引用命名空间using System.Reflection

class Program 
    {
        delegate string TestDelegate(string name);     
        static void Main(string[] args)
        {
           //*********************引导程序集************************//
            //Assembly ass = Assembly.LoadFrom(("SKY.ReflectDemo.dll")); 

           //Assembly ass=Assembly.GetAssembly(typeof(SKY.ReflectDemo.ReflectTest);
            Assembly ass = Assembly.Load("SKY.ReflectDemo");//功能同上  
            Console.Write(ass.FullName+"\n");

           //*********************显示该dll下所有的类***************//
           foreach (Type type in ass.GetTypes())
            {
                Console.Write(type.Name+"\n");               
            }

           //*********************显示该dll下指定类**************//
            Type itype = ass.GetType("SKY.ReflectDemo.ReflectTest");        
            Console.Write(itype.Name);
            Type itype1 = typeof(SKY.ReflectDemo.ReflectTest);                 
           //********************所有模块***********************//
            foreach (Module temp in ass.GetModules())
            {
                Console.WriteLine(temp.Assembly.FullName);
            }

            //********************创建该类的实例,后面的param为有参构造函数的参数******************//
            object[] param = { "test", 30 };//构造函数参数
            SKY.ReflectDemo.ReflectTest temp1 = (SKY.ReflectDemo.ReflectTest)Activator.CreateInstance(itype1, param);
            // SKY.ReflectDemo.ReflectTest temp1 = (SKY.ReflectDemo.ReflectTest)ass.CreateInstance("SKY.ReflectDemo.ReflectTest");
            Console.WriteLine(temp1.WriteNoPara());

            //******************************显示所有的共有方法************************************//
            MethodInfo[] methods = itype.GetMethods();
            Console.WriteLine("------------------------显示所有的共有方法-------------------------");
            foreach (MethodInfo temp in methods)
            { 
                Console.WriteLine(temp.Name);
            }

            //******************************显示特定方法************************************//
            Console.WriteLine("------------------------显示特定方法------------------------------");
            MethodInfo method1 = itype.GetMethod("WriteStaticInfo"); //带参的静态方法
            Console.WriteLine(method1.Name);
            object[] param1 = { "使用的是静态方法" };
            string s1 = (string)method1.Invoke(null, param1);
            Console.WriteLine("执行后:"+s1+"\n");

            MethodInfo method2 = itype.GetMethod("WriteStaticNoParam");//无参静态方法
            Console.WriteLine(method2.Name);
            string s2 = method2.Invoke(null, null) as string;
            Console.WriteLine("执行后:" + s2 + "\n");

            MethodInfo method3 = itype.GetMethod("WelcomeInfo");//带参的非静态方法
            Console.WriteLine(method3.Name);
            object[] param2 = { "使用的是带有参数的非静态方法" };
            string s3 = (string)method3.Invoke(temp1, param2);
            Console.WriteLine("执行后:" + s3 + "\n");

            MethodInfo method4 = itype.GetMethod("WriteNoPara");//无参非静态方法
            Console.WriteLine(method4.Name);
            string s4 = method4.Invoke(temp1, null) as string;
            Console.WriteLine("执行后:" + s4 + "\n");

            MethodInfo method5 = itype.GetMethod("WritePrivate", BindingFlags.NonPublic | BindingFlags.Instance);//无参私有非静态方法
            Console.WriteLine(method5.Name);
            string s5 = method5.Invoke(temp1, null) as string;
            Console.WriteLine("执行后:" + s5 + "\n");

            MethodInfo method6 = itype.GetMethod("Show");//返回类型为void的方法
            Console.WriteLine(method6.Name);
            object[]param3={"returnType is  void"};
            string s6 = method6.Invoke(temp1, param3) as string;
            Console.WriteLine(s6);

           //***********************************显示所有属性*********************************88//
            Console.WriteLine("------------------------显示所有属性------------------------------");
            PropertyInfo[] pros = itype.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            foreach (PropertyInfo temp in pros)
            {
                Console.WriteLine(temp.Name);
            }

            //***********************************显示特定属性*********************************88//
            Console.WriteLine("------------------------显示特定属性------------------------------");
            PropertyInfo proName = itype.GetProperty("Name");
            proName.SetValue(temp1, "testName",null);
            Console.WriteLine(proName.GetValue(temp1, null));

            //***********************************显示构造函数*********************************88//
            Console.WriteLine("------------------------显示构造函数------------------------------");
            ConstructorInfo[] cons = itype.GetConstructors();
            foreach (ConstructorInfo t in cons)
            {
                Console.WriteLine(t.ToString());
            }

            //***********************************显示特定构造函数形式*********************************88//
            Console.WriteLine("------------------------显示特定构造函数形式------------------------------");
            ConstructorInfo con1= itype.GetConstructor(new Type[] { typeof(string), typeof(int) });
            Console.WriteLine(con1);
            ConstructorInfo con2 = itype.GetConstructor(new Type[] { });
            Console.WriteLine(con2);

           //**************************************委托的使用*********************************************//
            Console.WriteLine("------------------------委托的使用------------------------------");
            TestDelegate td = (TestDelegate)Delegate.CreateDelegate(typeof(TestDelegate), temp1, "WelcomeInfo");//非静态方法
            Console.WriteLine(td("使用的是带有参数的非静态方法"));

            TestDelegate td2 = Delegate.CreateDelegate(typeof(TestDelegate), method1) as TestDelegate;//静态方法
            Console.WriteLine(td2("使用静态方法"));
           // TestDelegate td1 = new TestDelegate(SKY.ReflectDemo.ReflectTest.WriteStaticInfo);
           // Console.WriteLine(td1("使用的是带有参数的非静态方法222")); 同上

运行结果如下:

有什么不对,请大家批评指确。

posted @ 2009-09-19 20:07  幽境仼孓  阅读(955)  评论(1编辑  收藏  举报