C# 利用反射完成计算器可扩展功能
2021-02-11 03:17
一个主要的窗体程序,两个输入框,一个label
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using ProOperation;
using ProFactory;
namespace ProOperation
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//首先读取配置文件
string[] lines = File.ReadAllLines("Config.txt", Encoding.Default);
int x = 139;
int y = 154;
foreach (string item in lines)
{
//有几条数据,就创建几个按钮
Button btn = new Button();
btn.Location = new Point(x,y);
btn.Size = new Size(75, 23);
x += 80;
btn.Text = item;
btn.Click += new EventHandler(btn_Click);
this.Controls.Add(btn);//添加到窗体上
}
}
void btn_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
int n1 = Convert.ToInt32(textBox1.Text.Trim());
int n2 = Convert.ToInt32(textBox2.Text.Trim());
//获得简单工厂提供的父类对象
Operation oper = Factory.GetOper(btn.Text, n1, n2);
if (oper != null)
{
label1.Text = oper.GetResult().ToString();
}
else
{
MessageBox.Show("并没有此运算符");
}
}
}
}
四个类库产生dll
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProOperation;
namespace ProAdd
{
public class Add : Operation
{
//默认是调用的是无参构造。如果有参的话,就要这样调用,将参数,传给父类
public Add(int n1, int n2) : base(n1, n2){}
public override string Type
{
get { return "+"; }
}
public override int GetResult()
{
return this.NumberOne + NumberTwo;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProOperation;
using System.Reflection;
using System.IO;
namespace ProFactory
{
public class Factory
{
//工厂 返回父类, 但是其实父类中装的是子类对象
public static Operation GetOper(string type, int n1, int n2)
{
Operation oper = null;
//将前面add生成的dll文件放在debug下的plug文件夹下
//获得当前的路径,当前的文件夹的路径
string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"Plug");
//获得path路径下的所有文件的全路径
string[] files = Directory.GetFiles(path,"*.dll");
//遍历files,加载所有的程序集文件
foreach (string item in files)
{
//动态的获得程序集
Assembly ass = Assembly.LoadFile(item);
//ass.GetType()获得指定的程序
//ass.GetTypes() 获得所有的程序,不管是不是public
//获得程序集文件中所有公开的数据类型
Type[] types = ass.GetExportedTypes();
foreach (Type tt in types)
{
//判断当前数据类型是否是我们需要的数据类型
//tt是否是opeartion的子类,并且是抽象的
if (tt.IsSubclassOf(typeof(Operation)) && !tt.IsAbstract)
{
//创建子类对象 赋值给oper,返回值是object
//object o = Activator.CreateInstance(tt,n1,n2);
oper = (Operation)Activator.CreateInstance(tt, n1, n2);
if (type == oper.Type)
{
return oper;
}
else
{
oper = null;
}
}
}
}
return oper;
}
}
}
父类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ProOperation
{
public abstract class Operation
{
public int NumberOne { get; set; }
public int NumberTwo { get; set; }
//构造方法没有返回值,连void 都不要
public Operation(int n1, int n2)
{
this.NumberOne = n1;
this.NumberTwo = n2;
}
//记录子类的计算类型 +-*/
public abstract string Type { get; }
//获得结果
public abstract int GetResult();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProOperation;
namespace ProSub
{
public class Sub : Operation
{
public Sub(int n1, int n2) : base(n1, n2) { }
public override string Type
{
get { return "-"; }
}
public override int GetResult()
{
return this.NumberOne - this.NumberTwo;
}
}
}