目录
实验要求
构建一个components.txt文件,每行代表一个类(比如形状类Shape)的名字(这些类可以来自系统库,或者自己构造);程序逐行扫描该文件,构建对应的类的对象。
要求:
1.并把这些对象放到数组中;
2.列出每个类的字段、方法;
3.让用户选择,使得用户可以调用所需要的方法(操作)
4.系统随机选择对象(比如形状),随机的执行其操作。从而看系统演化。可能的话,进行界面展示
背景
反射的作用:
- 需要访问程序元数据的属性
- 检查和实例化程序集中的类型
- 在运行时构建新类型
- 执行后期绑定,访问在运行时创建的类型的方法
Step1.获得一个dll文件
- 新建一个C#控制台项目,添加一个.cs文件,此处使用一个Graphics.cs文件,代码内容如下。
- 用命令行编译此文件,获取它的dll文件。
- path C:\Windows\Microsoft.NET\Framework\v2.0.50727 //通常情况下csc.exe的文件夹位置
cd C:\ShapeClass\ShapeClass //项目位置
csc/target:library Graphic.cs
即可在项目路径下找到.dll文件
什么是dll文件?
.dll,动态链接库英文为DLL,是Dynamic Link Library的缩写。DLL是一个包含可由多个程序,同时使用的代码和数据的库。
为什么要使用dll文件?
当程序使用 DLL 时,具有以下的优点: 使用较少的资源,当多个程序使用同一个函数库时,DLL 可以减少在磁盘和物理内存中加载的代码的重复量。
推广模块式体系结构DLL 有助于促进模块式程序的开发。这可以帮助您开发要求提供多个语言版本的大型程序或要求具有模块式体系结构的程序。
什么是 csc.exe?
C#的编译器
命令:csc File.cs //编译该文件,生成exe文件
命令:csc/target:library File.cs // 编译该文件,生成dll文件
4. 新建一个Windows窗体应用(.Net Framework),将dll文件移动到该项目下
D:\C#课程学习\Draw\Draw\bin\Debug
Step2.构建一个txt文件
1. 构建一个Shape.txt文件,每行代表一个类.程序逐行扫描该文件,构建对应的类的对象,所以在其中写入:
Rectangle
Triangle
Sphere
Ellipse
2. 将此文件移动到相同dll所移动到的相同位置D:\C#课程学习\Draw\Draw\bin\Debug
Step3.利用反射查看成员信息
1.加入命名空间
using System.Reflection;
using System.Collections;
using System.IO;
2. 读取txt文件
string textpath = "Shape.txt";
FileStream Fp = File.OpenRead(textpath);
StreamReader STREAMR = new StreamReader(Fp, Encoding.Default);
Fp.Seek(0, SeekOrigin.Begin);
3.加载程序集
Assembly assembly = Assembly.LoadFrom("Graphics.dll");
//加载程序集:cs文件生成.dll文件,.dll文件是一个程序集
Console.WriteLine("name of assembley:" + assembly.GetName());
//写出程序集的名称
4. public ArrayList classList = new ArrayList(); //构建一个动态数组存放构建出的对象
5.
1. string classname //用于储存txt每行的内容
2. object[]ars={3,4} //和dll里内容相关的参数,不重要
3. //构建实体
函数的源代码
public object CreateInstance(string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object [] args, CultureInfo culture, object [] activationAttributes);
4.
Assembly类:通过它可以加载/了解/操作一个程序集
Type类:访问原数据的主要方式,Type类包括类类型/接口类型/数组类型/值类型/
枚举类型/类型参数/泛型类型定义,以及开放或封闭构造的泛型类型
GetType: Person pe=new Person();
Type t=pe.GetType();
//返回一个指定类型的Type对象,t为Person类型的Type对象
MethodInfo类:通过它可以找到方法信息
FieldInfo类:通过它可以找到字段信息
6.将得到的信息通过label控件显示在窗体上。
Step4.用户选择调用方法
在窗体上布置三个GroupBox,内置RadioButton,外置用于生成结果的Button。
函数的调用:meth[i].Invoke(object,null)
Step5.随机调用
- 随机数的生成
Random myrandom = new Random();
int classNum = myrandom.Next(0, 3);
Random 类
Random类默认的无参构造函数可以根据当前系统时钟为种子,进行一系列算法得出要求范围内的伪随机数.
Random rd = new Random();
int i = rd.Next();
- 得到随机数后的操作与“自主选择相同”
运行结果
代码
Graphics.cs
using System;
namespace ShapeClass
{
public class Rectangle
{
protected double x, y;
public Rectangle(double x1,double y1)
{
x = x1;
y = y1;
}
public double areaR()
{
return x * y;
}
public double lengthR()
{
return 2 * (x + y);
}
}
public class Triangle
{
protected double x, h;
public Triangle(double x1, double y1)
{
x = x1;
h = y1;
}
public double areaT()
{
return x * h/2;
}
public double lengthT()
{
return Math.Sqrt(x * x / 4 + h * h) * 2 + x;
}
}
public class Sphere
{
protected double r;
public Sphere(double r1)
{
r = r1;
}
public double areS()
{
return 3.14 * r * r;
}
public double lengthS()
{
return 6.28 * r;
}
}
public class Ellipse
{
protected double a, b;
public Ellipse(double a1,double b1)
{
a = a1;
b = b1;
}
public double areaE()
{
return 3.14 * a * b;
}
public double lengthE()
{
return 6.28* b + 4 * (a - b);
}
}
}
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using System.Collections;
namespace Draw
{
public partial class Form1 : Form
{
public ArrayList classList = new ArrayList();
public Form1()
{
InitializeComponent();
Assembly assembly = Assembly.LoadFrom("Graphics.dll");//加载程序集:cs文件生成.dll文件,.dll文件是一个程序集
Console.WriteLine("name of assembley:" + assembly.GetName());//写出程序集的名称
//构建对应的类的对象
string textpath = "Shape.txt";
FileStream Fp = File.OpenRead(textpath);
StreamReader STREAMR = new StreamReader(Fp, Encoding.Default);
Fp.Seek(0, SeekOrigin.Begin);
string classname;
while (STREAMR.Peek() > -1)
{
classname = STREAMR.ReadLine();
object[] ars = { 3, 4 };
object shapex = assembly.CreateInstance("Graphics." + classname, true, BindingFlags.Default, null, ars, null, null);
classList.Add(shapex);
Type reshape = shapex.GetType();
if (shapex != null)
label2.Text = label2.Text+"\n\n\n\n\n\n"+Convert.ToString(classList.Count)+"类名:"+reshape.Name;
//列出每个类的字段、方法;
MethodInfo[] methodnum = reshape.GetMethods();
label4.Text = label4.Text+ "\n\n\n\n\n" + reshape.FullName+"的方法个数:" + Convert.ToString(methodnum.Length)+"\n";
for (int j = 0; j < methodnum.Length; j++)
{
label5.Text = label5.Text + Convert.ToString(j + 1) + "." + methodnum[j].Name+"\n";
}
label5.Text = label5.Text + "\n";
//列出字段
FieldInfo[] tagnum = reshape.GetFields();
label6.Text =label6.Text+ "\n\n\n\n\n" + reshape.FullName + "的字段个数:"+ Convert.ToString(tagnum.Length ) + "\n";
for (int k = 0; k < tagnum.Length; k++)
{
Console.WriteLine("({0}){1}", k + 1, tagnum[k].Name);
label7.Text = label7.Text + Convert.ToString(k + 1) + "." + tagnum[k].Name + "\n";
}
}
}
private void button_Click(object sender, EventArgs e)
{
if(radioButton2.Checked )
{
//随机数
Random myrandom = new Random();
int classNum = myrandom.Next(0, 3);
object myobject = classList[classNum];//随机选择一个类
int numfangfa;
while (true)
{
numfangfa = myrandom.Next(1, 6);
if (numfangfa != 3&&numfangfa!=6)
break;
}
Type leixing = classList[classNum].GetType();
MethodInfo[] methoddn = leixing.GetMethods();
string s = Convert.ToString(methoddn[numfangfa - 1].Invoke(myobject, null));
label1.Text =leixing .Name+"+"+ methoddn[numfangfa - 1].Name+":"+ methoddn[numfangfa - 1].Invoke(myobject, null);
}
else if(radioButton1.Checked ) //即用户选择了“自主调用”的按钮
{
if(radioButton3.Checked ) //选择了第一种形状
{
object myshape = classList[0];
Type shapelei = classList[0].GetType();
MethodInfo[] meth = shapelei.GetMethods();
if(radioButton10.Checked ) //选择了不同的方法按钮
{
string s= Convert.ToString(meth[0].Invoke(myshape, null));
label1.Text = shapelei.Name + "+" + meth[0].Name + ":" + meth[0].Invoke(myshape, null);
}
else if (radioButton9.Checked)
{
string s = Convert.ToString(meth[1].Invoke(myshape, null));
label1.Text = shapelei.Name + "+" + meth[1].Name + ":" + meth[1].Invoke(myshape, null);
}
else if (radioButton8.Checked)
{
string s = Convert.ToString(meth[3].Invoke(myshape, null));
label1.Text = shapelei.Name + "+" + meth[3].Name + ":" + meth[3].Invoke(myshape, null);
}
else if (radioButton7.Checked)
{
string s = Convert.ToString(meth[4].Invoke(myshape, null));
label1.Text = shapelei.Name + "+" + meth[4].Name + ":" + meth[4].Invoke(myshape, null);
}
}
if (radioButton4.Checked)
{
object myshape = classList[1];
Type shapelei = classList[1].GetType();
MethodInfo[] meth = shapelei.GetMethods();
if (radioButton10.Checked)
{
string s = Convert.ToString(meth[0].Invoke(myshape, null));
label1.Text = shapelei.Name + "+" + meth[0].Name + ":" + meth[0].Invoke(myshape, null);
}
else if (radioButton9.Checked)
{
string s = Convert.ToString(meth[1].Invoke(myshape, null));
label1.Text = shapelei.Name + "+" + meth[1].Name + ":" + meth[1].Invoke(myshape, null);
}
else if (radioButton8.Checked)
{
string s = Convert.ToString(meth[3].Invoke(myshape, null));
label1.Text = shapelei.Name + "+" + meth[3].Name + ":" + meth[3].Invoke(myshape, null);
}
else if (radioButton7.Checked)
{
string s = Convert.ToString(meth[4].Invoke(myshape, null));
label1.Text = shapelei.Name + "+" + meth[4].Name + ":" + meth[4].Invoke(myshape, null);
}
}
if (radioButton5.Checked)
{
object myshape = classList[2];
Type shapelei = classList[2].GetType();
MethodInfo[] meth = shapelei.GetMethods();
if (radioButton10.Checked)
{
string s = Convert.ToString(meth[0].Invoke(myshape, null));
label1.Text = shapelei.Name + "+" + meth[0].Name + ":" + meth[0].Invoke(myshape, null);
}
else if (radioButton9.Checked)
{
string s = Convert.ToString(meth[1].Invoke(myshape, null));
label1.Text = shapelei.Name + "+" + meth[1].Name + ":" + meth[1].Invoke(myshape, null);
}
else if (radioButton8.Checked)
{
string s = Convert.ToString(meth[3].Invoke(myshape, null));
label1.Text = shapelei.Name + "+" + meth[3].Name + ":" + meth[3].Invoke(myshape, null);
}
else if (radioButton7.Checked)
{
string s = Convert.ToString(meth[4].Invoke(myshape, null));
label1.Text = shapelei.Name + "+" + meth[4].Name + ":" + meth[4].Invoke(myshape, null);
}
}
if (radioButton6.Checked)
{
object myshape = classList[3];
Type shapelei = classList[3].GetType();
MethodInfo[] meth = shapelei.GetMethods();
if (radioButton10.Checked)
{
string s = Convert.ToString(meth[0].Invoke(myshape, null));
label1.Text = shapelei.Name + "+" + meth[0].Name + ":" + meth[0].Invoke(myshape, null);
}
else if (radioButton9.Checked)
{
string s = Convert.ToString(meth[1].Invoke(myshape, null));
label1.Text = shapelei.Name + "+" + meth[1].Name + ":" + meth[1].Invoke(myshape, null);
}
else if (radioButton8.Checked)
{
string s = Convert.ToString(meth[3].Invoke(myshape, null));
label1.Text = shapelei.Name + "+" + meth[3].Name + ":" + meth[3].Invoke(myshape, null);
}
else if (radioButton7.Checked)
{
string s = Convert.ToString(meth[4].Invoke(myshape, null));
label1.Text = shapelei.Name + "+" + meth[4].Name + ":" + meth[4].Invoke(myshape, null);
}
}
}
}
}
}