今天刚接触到反射,学习了几个小时,写了个例子,说说自己的理解,反射就是通过对象的外部可以了解到它的内部,通过反射可以在程序运行期间获得详细的内部结构,例如现在有一个类C的对象C1正在运行,此时,你想知道C1的详细内部情况怎么办,假如,要根据C1的运行状态创建一个新的类C2,怎么办?这个时候,就体现了反射的作用,他可以根据C1而获得类C的详细内部结构(字段、属性、方法),根据这些创建需要的类C2。
先熟悉几个概念,Type是什么东西?Type是一个类,是表示类型的,例如Type t = typeof(int);在这里需要熟悉的是一些Type的方法,他的方法很丰富,可以获得类型t的构造函数,属性,字段,判断是否抽象,是否数组,等等很多。
对Invoke函数的理解。
Activator类,Contains methods to create types of objects locally or remotely, or obtain references to existing remote objects. This class cannot be inherited.
还有一些类,例如MemberInfo,成员信息类,ConstructorInfo构造函数类,ParameterInfo参数类,FieldInfo字段类,PropertyInfo属性类等等,他们的用法,会用一个,其他的基本也就会了
看看例子。
类 NewClass。
这里写代码片
public class NewClass
{
private String Name;
public string Sex;
public NewClass(string sex)
{
this.Sex = sex;
}
public NewClass(string name, string sex)
{
this.NameInfo = name;
this.Sex = sex;
}
public NewClass()
{
MessageBox.Show("没有参数的构造函数");
}
public string NameInfo
{
get { return Name; }
set { this.Name = value; }
}
public string SexInfo
{
get { return Sex; }
set { this.Sex = value; }
}
}
private void button1_Click(object sender, EventArgs e)
{
//用构造函数动态生成对象:
richTextBox1.AppendText("*************************调用两个参数的构造函数***************************" + "\n");
Type tC = typeof(NewClass);//获取NewClass类型
Type[] pt = new Type[2];
pt[0] = typeof(string);
pt[1] = typeof(string);
ConstructorInfo ci = tC.GetConstructor(pt);//找到匹配的构造函数
string[] obj = new string[2] { "Dany", "man" };
object o = ci.Invoke(obj);//根据参数构造对象
richTextBox1.AppendText("object1 name is :" + ((NewClass)o).NameInfo + "\n");
richTextBox1.AppendText("object1 sex is :"((NewClass)o).SexInfo + "\n");
richTextBox1.AppendText("*************************调用一个参数的构造函数****************************" + "\n");
Type tC2 = typeof(NewClass);
Type[] pt2 = new Type[1];
pt2[0] = typeof(string);
ConstructorInfo ci2 = tC2.GetConstructor(pt2);
object[] obj2 = new object[1] { "man" };
object o2= ci2.Invoke(obj2);
richTextBox1.AppendText("object2 name is :" + ((NewClass)o2).NameInfo + "\n");
richTextBox1.AppendText("object2 sex is :" + ((NewClass)o2).SexInfo + "\n");
richTextBox1.AppendText("*************************调用没有参数的构造函数****************************" + "\n");
//暂时不会写,不知道怎样才能调用没有参数的构造函数
/*
Type tC3 = typeof(NewClass);
Type[] pt3 = new Type[1];
pt3[0] = typeof(void);
ConstructorInfo ci3 = tC3.GetConstructor(pt3);
object[] obj3 = new object[1] {"" };
object o3 = ci3.Invoke();
richTextBox1.AppendText("object3 name is :" + ((NewClass)o3).NameInfo + "\n");
richTextBox1.AppendText("object3 sex is :" + ((NewClass)o3).SexInfo + "\n");
* */
//用Activator生成对象:
richTextBox1.AppendText("*************************调用Activator生成对象****************************" + "\n");
Type t4 = typeof(NewClass);
object[] obj4 = new object[2] { "Jim", "man" };
object o4 = Activator.CreateInstance(t4, obj4);
richTextBox1.AppendText("object4 name is :" + ((NewClass)o4).NameInfo + "\n");
richTextBox1.AppendText("object4 sex is :" + ((NewClass)o4).SexInfo + "\n");
//用反射生成对象:
richTextBox1.AppendText("*************************使用反射生成对象****************************" + "\n");
NewClass nc = new NewClass("Jack", "man");
Type t5 = nc.GetType();
object obj5 = Activator.CreateInstance(t5);//会先调用没有参数的构造函数,不解...........
FieldInfo fi = t5.GetField("Sex");
fi.SetValue(obj5, "woman");//必须是Public的字段才行
PropertyInfo pi1 = t5.GetProperty("NameInfo");//属性
pi1.SetValue(obj5, "Jack2", null);
richTextBox1.AppendText("object5 name is :" + ((NewClass)obj5).NameInfo + "\n");
richTextBox1.AppendText("object5 sex is :" + ((NewClass)obj5).SexInfo + "\n");
}
在这段代码中,反射是怎样实现从外部透析内部呢?总结一下,首先 ,要获得对象的类型Type t;然后使用Activator类的静态函数public static object CreateInstance(Type type)生成新的对象,这个函数的作用是根据指定的类型来创建对象,接下来根据类型t来获得具体的属性、字段,然后对他进行设置值,注意这个设置的是新的对象的,这就是最简单的思路了。
反射不仅可以根据对象获得类的内部结构,也可以通过对象获得程序集,非常强大,还有待我进一步学习。
有哪位大神能够帮我解决一下,这个代码中的两个问题,第一个问题,是我代码中注释掉的那部分代码,用动态方法,怎样可以调用没有参数的构造函数。
第二个问题,使用Activator.CreateInstance(Type);为什么会先调用没有参数的构造函数?