反射

步步为营 C# 技术漫谈 一、反射机制

反射提供了描述程序集、模块和类型的对象(Type 类型)。 可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。 如果代码中使用了特性,可以利用反射来访问它们。 有关更多信息,请参见 利用特性扩展元数据

 System.Reflection.Assembly ass = Assembly.LoadFile(@"F:\MyApplication\HampBase\Hamp.Base.Util\obj\Debug\Hamp.Base.Util.dll");
 //object obj = ass.CreateInstance("Hamp.Base.Util.DynamicObjectEx");//必须使用名称空间+类名称
 Type type = ass.GetType(" Hamp.Base.Util.DateTimeHelper");//必须使用名称空间+类名称
 MethodInfo m = type.GetMethod("ToGMTString");//方法的名称
 string s = (string)m.Invoke(null, new object[] { DateTime.Now }); //调用静态方法
 Console.WriteLine("将时间转成GMT格式的字符串:{0}", s);

 

using System;
using System.Reflection;

namespace 反射
{
    class Program
    {
        static void Main(string[] args)
        {
            ReflcetionTest test = new ReflcetionTest();
            //test.AssemblyTest();
            //test.TypeTest();
            //test.ClassMemberInfo();
            test.OperMembers();
            Console.ReadLine();
        }
    }
    /// <summary>
    /// 调试类。  
    /// </summary> 
    public class ReflcetionTest
    {
        /// <summary> 
        /// Assembly类:程序集信息。  
        /// </summary> 
        public void AssemblyTest()
        {
            Console.WriteLine("\t\t" + "------------Assembly类的使用------------");
            Console.WriteLine();
            //获取当前所执行代码的程序集信息 
            Assembly myAssembly = Assembly.GetExecutingAssembly();
            Console.WriteLine("获取程序集位置:{0}", myAssembly.CodeBase);
            Console.WriteLine("获取此程序集的入口点:{0}", myAssembly.EntryPoint);
            Console.WriteLine("获取程序集的显示名称:{0}", myAssembly.FullName);
            Console.WriteLine("获取包含当前程序集清单的模块:{0}", myAssembly.ManifestModule);
            Console.WriteLine();
            //获取当前程序集的名称及信息 
            AssemblyName asmName = myAssembly.GetName();
            Console.WriteLine("获取或设置程序集的简单名称:{0}", asmName.Name);
            Console.WriteLine("获取程序集的全名:{0}", asmName.FullName);
            Console.WriteLine("获取或设置程序集的RUL位置:{0}", asmName.CodeBase);
            Console.WriteLine("获取或设置程序集的主版本号、次版本号、内部版本号和修订版本号:{0}", asmName.Version);
            Console.WriteLine();
            //获取当前程序集的版本相关信息 
            System.Version asmVersion = asmName.Version;
            Console.WriteLine("获取当前程序集的主版本号:{0}", asmVersion.Major);
            Console.WriteLine("获取当前程序集的次版本号:{0}", asmVersion.Minor); 
            Console.WriteLine("获取当前程序集的内部版本号:{0}", asmVersion.Build);
            Console.WriteLine("获取当前程序集的修订版本号:{0}", asmVersion.MajorRevision);
            Console.WriteLine();
        }

        /// <summary> 
        /// Type类:检索类信息。    
        /// </summary> 
        public void TypeTest()
        {
            Console.WriteLine("\t\t" + "------------Type类的使用------------"); Console.WriteLine();
            //设置被检索的类 
            Type myType = Type.GetType("反射.Sudent");
            //检索信息 
            Console.WriteLine("获取当前成员名称:{0}", myType.Name);
            Console.WriteLine("获取当前完全限定名(不包括程序集):{0}", myType.FullName); 
            Console.WriteLine("获取当前Type所在的空间名称:{0}", myType.Namespace);
            Console.WriteLine();
            //检索类成员 
            Console.WriteLine("获取方法相关信息:{0}", myType.GetMethod("MetName").ToString());
            Console.WriteLine("获取属性相关信息:{0}", myType.GetProperty("ProName").ToString());
            Console.WriteLine("获取字段相关信息:{0}", myType.GetField("mName", BindingFlags.NonPublic | BindingFlags.Instance).ToString()); 
            Console.WriteLine();
            //设定自己为被检索的类 
            Type myThis = this.GetType();
        }
        /// <summary>         
        /// 访问类成员。    
        /// </summary> 
        public void ClassMemberInfo()
        {
            //指定被访问的类。 
            //Type WMtype = Type.GetType("反射.Sudent"); 使用这个时无法获取属性值。  
            // 或者这样指定被访问的类。使用这个时可以获取属性值,因为要使用到myWeiMei对象实例。           
            Sudent myWeiMei = new Sudent();        
            Type WMtype = myWeiMei.GetType();  
            Console.WriteLine("\t\t" + "---MemberInfo访问类的所有成员---"); 
            Console.WriteLine();
            //MemberInfo类:遍历被访问类的所有成员。 
            MemberInfo[] members = WMtype.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | 
                BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly); 
            foreach (MemberInfo member in members)
            {
                Console.WriteLine("成员名称:{0}---" + "成员类型:{1}", member.Name, member.MemberType);
            }
            Console.WriteLine();
            //-------------------------        
            Console.WriteLine("\t\t" + "---MethodInfo访问类的方法---"); 
            Console.WriteLine();
            //MethodInfo类:遍历被访问类的方法。 
            MethodInfo[] methods = WMtype.GetMethods(BindingFlags.Public | BindingFlags.NonPublic |
                  BindingFlags.Instance | BindingFlags.DeclaredOnly); 
            foreach (MethodInfo method in methods)
            {
                Console.WriteLine("方法名称:{0}---" + "方法类型:{1}", method.Name, method.ReturnType);
            }
            Console.WriteLine();
            //--------------------------          
            Console.WriteLine("\t\t" + "---PropertyInfo访问类的属性---"); 
            Console.WriteLine();
            //PropertyInfo类:遍历被访问类的属性。 
            PropertyInfo[] propertys = WMtype.GetProperties(BindingFlags.Public | BindingFlags.NonPublic |
                BindingFlags.Instance | BindingFlags.DeclaredOnly);
            foreach (PropertyInfo property in propertys)
            {
                Console.WriteLine("属性名称:{0}---属性类型:{1}---属性值:{2}", property.Name, property.PropertyType, property.GetValue(myWeiMei, null));
            }
            Console.WriteLine();
            //--------------------------              
            Console.WriteLine("\t\t" + "---FieldInfos访问类的字段----");
            Console.WriteLine();
            //FieldInfo类:遍历被访问类的字段。 
            FieldInfo[] fields = WMtype.GetFields(BindingFlags.Public | BindingFlags.NonPublic |
                BindingFlags.Instance | BindingFlags.DeclaredOnly);
            foreach (FieldInfo field in fields)
            {
                Console.WriteLine("字段名称:{0}---" + "字段类型:{1}", field.Name, field.FieldType);
            }
            Console.WriteLine();
            //--------------------------              
            Console.WriteLine("\t\t" + "---ConstructorInfo访问类的构造函数---"); 
            Console.WriteLine();
            //ConstructorInfo类:遍历被访问类的构造函数。 
            ConstructorInfo[] constructors = WMtype.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | 
                BindingFlags.Instance | BindingFlags.DeclaredOnly);
            foreach (ConstructorInfo constructor in constructors)
            {
                Console.WriteLine("构造函数名称:{0}---" + "构造函数类型:{1}", constructor.Name, constructor.MemberType);
            }
            Console.WriteLine();
            //---------------------------  
            Console.WriteLine("\t\t" + "---EventInfo用于访问类的事件元数据---");
            Console.WriteLine();
            //EventInfo类:遍历被访问类的事件。 
            EventInfo[] eventinfos = WMtype.GetEvents(BindingFlags.Public | BindingFlags.NonPublic | 
                BindingFlags.Instance | BindingFlags.DeclaredOnly);
            foreach (EventInfo eventinfo in eventinfos)
            {
                Console.WriteLine("事件名称:{0}---" + "成员类型:{1}", eventinfo.Name, eventinfo.MemberType);
            }
            Console.WriteLine();

            //---------------------------       
            Console.WriteLine("\t\t" + "---ParameterInfo用于表示参数的元数据---");         
            Console.WriteLine(); 
            //ParameterInfo类:检索Student类中的MetName方法()的参数          
            MethodInfo myMethod = WMtype.GetMethod("TestName");           
            ParameterInfo[] paramets = myMethod.GetParameters();         
            int count = 0foreach (ParameterInfo paramet in paramets)
            {
                count++;
                Console.WriteLine("参数" + count + "名称:{0};类型:{1}", paramet.Name, paramet.ParameterType);
            }
            Console.WriteLine();
        }
        /// <summary>        
        ///  调用类成员。 
        /// 第一种调用方法就是使用MethodInfo类调用方法、PropertyInfo类调用属性、FieldInfo类调用字段、EventInfo类调用事件、ConstructorInfo类调用构造函数。 
        /// 第二种调用方法就是使用Type类的InvokeMember()方法。      
        /// </summary> 
        public void OperMembers()
        {
            //指定被访问的类。 
            Sudent weiMeiObj = new Sudent(); 
            Type WMtype = weiMeiObj.GetType();
            // 或者这样指定被访问类(注意:静态类时GetType("反射.类名"))             // Type WMtype = Type.GetType("反射.WeiMei");  
            //操作方法 
            string[] parName = new String[] { "WeiMeiHua" };  //方法参数的值           
            MethodInfo method = WMtype.GetMethod("MetName");          
            method.Invoke(weiMeiObj, parName); 
            Console.WriteLine("操作方法改变值后为:{0}", weiMeiObj.ProName);
            //操作属性 
            PropertyInfo proper = WMtype.GetProperty("ProName");
            proper.SetValue(weiMeiObj, "HuaWeiMei", null);   //SetValue为设置属性的值,GetValue为获取属性的值。        
            Console.WriteLine("操作属性改变值后为:{0}", weiMeiObj.ProName);  
            //操作字段 
            FieldInfo field = WMtype.GetField("mName", BindingFlags.NonPublic | BindingFlags.Instance); 
            field.SetValue(weiMeiObj, "WeiMei");            //与属性相同。           
            Console.WriteLine("操作字段改变值后为:{0}", weiMeiObj.ProName);         
            Console.WriteLine();  
            //操作事件 
            EventInfo eventInfo = WMtype.GetEvent("WMShout");
            Console.WriteLine("声明该成员的类:{0}", eventInfo.DeclaringType); 
            Console.WriteLine("事件名称:{0}", eventInfo.Name);
            Console.WriteLine("事件类型:{0}", eventInfo.MemberType);
            Console.WriteLine();
            //操作构造函数 
            ConstructorInfo consInfo1 = WMtype.GetConstructor(System.Type.EmptyTypes);
        }

    }
    /// <summary> 
    /// 被检索/访问的类。   
    /// </summary> 
    public class Sudent
    {
        //字段 
        private string mName;
        private string mSix; 
        private int mAge;
        //构造函数 
        public Sudent()
        {
            mName = "LiuWeiMei"; mSix = "gril"; mAge = 20;
        }
        public Sudent(string name, string six, int age)
        {
            mName = name; mSix = six; mAge = age;
        }
        //属性 
        public string ProName
        {
            get { return mName; }
            set { mName = value; }
        }
        public string ProSix
        {
            get { return mSix; }
            set { mSix = value; }
        }
        public int ProAge
        {
            get { return mAge; }
            set { mAge = value; }
        }
        private string ProLoveYou
        {
            get { return "这是一个秘密,只有我才知道"; }
        }
        //方法 
        public string MetName(string herName)
        {
            this.mName = herName; return mName;
        }
        public string MetSix(string herSix)
        {
            this.mSix = herSix; return mSix;
        }
        public int MetAge(int herAge)
        {
            this.mAge = herAge; return mAge;
        }
        private string MetLoveYou()
        {
            return "这是一个秘密,只有我才知道";
        }
        public string TestName(string herName, int like, float love)
        {
            this.mName = herName; return mName;
        }
        //声明委托 
        public delegate string WMName(string wmName);
        //声明事件1 
        public event WMName WMShout;
        //声明事件2 
        private event WMName WMLove;
    }
}
反射Demo

 

参考文件:

反射(C# 和 Visual Basic)

.NET Framework 中的反射
 

 

 

posted on 2014-12-04 16:05  二狗你变了  阅读(170)  评论(0)    收藏  举报

导航