C# Reflection 反射 入门

在C#的using System.Reflection 中有反射这样一个东西。

它可以获取一个程序集中命名空间,类,类成员的信息,就算是private的成员也会暴露出来(赤裸裸的~)。并且反射还可以使我们动态绑定对象(?应该是这样称呼),使得程序灵活性更大。 还可以结合工厂模式进行反射工厂模式的设计(这个是我一直想学习的,可以应用于游戏中的物品创建,技能创建)。

好,讲了这么多,开始说反射。

首先,反射有一个核心就是Type。们知道类存储着我们定义的模板的信息,但是type属于更上一层的,它存储着类的信息。虽然本质上它也是类啦。

如何获取Type呢,我列举了几种方法。

            Person p1 = new Person();

            Type t = p1.GetType();
            Type t1 = Type.GetType("Person");
            Type t2 = typeof(Person);

好现在有了Type,那么该引出反射的其他对象了。

Type对象里面有很多方法,主要是Get开头的,如GetMembers,可以获取很多类的信息。还有一些Is开头的,也可以获取很多类的信息。如IsSubClassOf(),用来判断是否是一个类的子类。

现在有四个对象。分别是Assembly(程序集),Module(模块,就是C#中的命名空间),Type(刚讲的),Member(类的成员,包括:字段,构造函数,方法,属性等)。他们的包含关系是左边最大,依次减小。

这些信息我们都可以获得,并且他们相互找到。

            Person p1 = new Person();

            Type t = p1.GetType();

            Assembly ass = t.Assembly;
            Module mo = t.Module;
            MemberInfo[] ms = t.GetMembers();

对于程序集,有这么些方法可以得到

            Assembly ass1 = Assembly.Load("AssemblyName");
            Assembly ass2 = typeof(Person).Assembly;
            Assembly ass3 = typeof(Person).Module.Assembly;

对于模块也有一些类似的方式可以得到。我就不列举了。

关于探索如何利用反射来获取程序集中某个类的信息,可以参考我另一篇博文

https://mp.csdn.net/postedit/82353085

好,下面讲一下如何动态创建对象。我现在只知道一个类的名字,我想创建这个类的对象,我就可以动态创建。

这个在游戏的技能和物体设计很重要。对于一个武器,我只要知道一个武器类的名字,并且还有一些参数,那么我就可以创建一个武器对象。

Type  t  =  Type.GetType("System.Data.DataTable,System.Data,Version=1.0.3300.0,  Culture=neutral,  PublicKeyToken=b77a5c561934e089");
DataTable  table  =  (DataTable)Activator.CreateInstance(t);

还可以根据参数和构造函数创建对象

namespace  TestSpace  
{
  public  class  TestClass
      {
      private  string  _value;
      public  TestClass(string  value)  
    {
      _value=value;
      }
  }
}
…
Type  t  =  Type.GetType(“TestSpace.TestClass”);
Object[]  constructParms  =  new  object[]  {“hello”};  //构造器参数
TestClass  obj  =  (TestClass)Activator.CreateInstance(t,constructParms);
…

还可以动态调用方法

namespace  TestSpace  
{
  public  class  TestClass
      {
      private  string  _value;
      public  TestClass(string  value)  
    {
      _value=value;
      }
  }
}
…
Type  t  =  Type.GetType(“TestSpace.TestClass”);
Object[]  constructParms  =  new  object[]  {“hello”};  //构造器参数
TestClass  obj  =  (TestClass)Activator.CreateInstance(t,constructParms);
…

总结一下,C#使用反射创建对象最后还是有一步强制转换(TestClass),我无法绕过这一步而仅仅通过一个string的类名创建指定类型的对象。但是我在这一步可以不强制转换,就将这个对象当做一个Object存放在内存,但他实际上是我TestClass的类型,所以对于这个对象,我可以在之后的使用中再强制转化成TestClass。

具体的东西可以参考

https://www.cnblogs.com/wangshenhe/p/3256657.html

猜你喜欢

转载自blog.csdn.net/qq_14812585/article/details/87985058