C# 利用反射完成计算器可扩展功能

2021-02-11 03:17

阅读:1272

一个主要的窗体程序,两个输入框,一个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;
        }
    }
}


评论


亲,登录后才可以留言!