C#知识点-16(计算器插件开发、事件、递归、XML)

计算器插件开发

1、Calculator.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace Calculator_DLL
{//用来明确所有插件开发人员的开发规范public abstract class Calculator{public int NumberOne { get;set; }public int NumberTwo { get;set; }public abstract string Oper { get; }//抽象属性public Calculator(int n1,int n2){this.NumberOne = n1;this.NumberTwo = n2;}//提供一个计算的方法,具体的计算公式,留给插件开发人员public abstract int GetResult();}
}

2、Calculator_Add.cs

using Calculator_DLL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace Calculator_DLL_Add
{public class Calculator_Add : Calculator{public Calculator_Add(int n1, int n2) : base(n1, n2){}public override string Oper { get { return "+"; } }public override int GetResult(){return this.NumberOne + this.NumberTwo;}}
}

3、Calculator_Sub.cs

using Calculator_DLL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace Calculator_DLL_Sub
{public class Calculator_Sub : Calculator{public Calculator_Sub(int n1, int n2) : base(n1, n2){}public override string Oper { get { return "-"; } }public override int GetResult(){return this.NumberOne-this.NumberTwo;}}
}

4、Calculator_Factory.cs

using Calculator_DLL;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;namespace Calculator_Factory_DLL
{/// <summary>/// 计算器插件的工厂,根据用户的选择,返回对应的计算对象(插件对象)/// </summary>public class Calculator_Factory{/// <summary>/// 根据用户选择的操作符,创建对应的插件对象(是用父类屏蔽了所有子类插件对象)/// </summary>/// <param name="oper">用户选择的操作符</param>/// <param name="n1">数字1</param>/// <param name="n2">数字2</param>/// <returns>对应的计算插件对象</returns>public static Calculator GetCalculator(string oper,int n1,int n2){Calculator cal = null;//Assembly:表示程序集 GetExecutingAssembly():获取包含当前执行的代码的程序集  Location:位置,也就是路径string path = Assembly.GetExecutingAssembly().Location;//GetDirectoryName():返回指定路径字符串的目录信息path = Path.GetDirectoryName(path);//DLL程序集的上一个目录,也就是Debug目录path = Path.Combine(path, "Plug-in-Components");//读取文件夹下的所有插件(Add、Sub)string[] files = Directory.GetFiles(path);//遍历所有类库文件,从里面找到我们规范的类型(类型要求:继承了Calculator,并且重写了其中的抽象成员,并且不是抽象的)foreach (var file in files){//LoadFile():加载指定路径上的程序集文件的内容Assembly ass = Assembly.LoadFile(file);//GetExportedTypes():获取程序集中定义的公共类型Type[] types = ass.GetExportedTypes();//判断类型是否为我们需要的类型foreach (var type in types){//开始筛选//IsAssignableFrom():确定指定类型的实例是否能分配给当前实例(看有没有继承关系)//IsAbstract:判断当前类型是否是抽象的if (typeof(Calculator).IsAssignableFrom(type)&&!type.IsAbstract){//创建type的对象object o =Activator.CreateInstance(type,n1,n2);cal = o as Calculator;//如果计算对象的Oper属性==用户传入的Oper值if (cal.Oper==oper){return cal;}}}}return cal;}}
}

5、Form1.cs

using Calculator_DLL;
using Calculator_Factory_DLL;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace 插件记事本
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){//1、读取配置文件,创建对应的按钮对象string path = Assembly.GetExecutingAssembly().Location;path=Path.GetDirectoryName(path);path = Path.Combine(path, "CalculatorConfig.txt");//2、读取配置文件string[] operLines = File.ReadAllLines(path);int x = 100;//3、创建按钮对象for (int i = 0; i < operLines.Length; i++){Button btn = new Button();btn.Text = operLines[i];btn.Size = new Size(75, 23);btn.Location = new Point(326 + i * x, 257);btn.Click += Btn_Click;this.Controls.Add(btn);}}private void Btn_Click(object sender, EventArgs e){Button btn = sender as Button;string oper = btn.Text;Calculator cal = Calculator_Factory.GetCalculator(oper,int.Parse(txtNumberOne.Text),int.Parse(txtNumberTwo.Text));if (cal != null){lblResult.Text = cal.GetResult().ToString();}}}
}

事件

概念:事件,就是一个类型安全的委托(事件是安全的,因为在类的外部,事件只能被赋值,而不能被调用)
事件的三个重要组成部分:注册事件、触发事件、响应事件

递归

概念:在方法中,自己调用自己。必须在满足某个条件的时候,退出递归

递归查找所有的文件夹和文件

        private void Form1_Load(object sender, EventArgs e){//递归加载指定目录下,所有的文件夹和文件string path = @"C:\Windows\Microsoft.NET\Framework64\v4.0.30319";LoadData(path, treeView2.Nodes);}private void LoadData(string path, TreeNodeCollection nodes){//1、获取该路径下所有的文件夹string[] dirs = Directory.GetDirectories(path);//1.1 把所有的子目录的路径,添加到Treeview上foreach (var item in dirs){//tn就是根节点TreeNode tn = nodes.Add(Path.GetFileName(item));LoadData(item, tn.Nodes);}//2、获取该路径下所有的文件string[] files = Directory.GetFiles(path);foreach (var item in files){nodes.Add(Path.GetFileName(item));}}

XML

XML:可扩展的标记语言

通过代码创建XML文档

    internal class Program{static void Main(string[] args){//1、在内存中,创建XML文档对象XmlDocument xml = new XmlDocument();//2、创建文档声明XmlDeclaration dec = xml.CreateXmlDeclaration("1.0", "utf-8", null);//2.1 把创建的文档声明,添加到xml文档中xml.AppendChild(dec);//3、创建根节点XmlElement books = xml.CreateElement("Books");//3.1 把创建的根节点,添加到xml文档中xml.AppendChild(books);//4.1、给根节点,添加对应的属性XmlElement book1 = xml.CreateElement("Book");//Attribute :特性  [Serilizeble]  Property:属性XmlAttribute book1_id = xml.CreateAttribute("ID");//给属性赋值book1_id.Value = "00001";//把属性跟Book标签绑定到一起book1.Attributes.Append(book1_id);books.AppendChild(book1);//4.2 给根节点,添加对应的子节点XmlElement book1_name = xml.CreateElement("Name");//给子节点赋值book1_name.InnerText = "金瓶梅";book1.AppendChild(book1_name);//4.2 给根节点,添加对应的子节点XmlElement book1_author = xml.CreateElement("Author");//给子节点赋值book1_author.InnerText = "西门大官人";book1.AppendChild(book1_author);//4.2 给根节点,添加对应的子节点XmlElement book1_price = xml.CreateElement("Price");//给子节点赋值book1_price.InnerText = "10";book1.AppendChild(book1_price);//4.1、给根节点,添加对应的属性XmlElement book2 = xml.CreateElement("Book");//Attribute :特性  [Serilizeble]  Property:属性XmlAttribute book2_id = xml.CreateAttribute("ID");//给属性赋值book2_id.Value = "00002";//把属性跟Book标签绑定到一起book2.Attributes.Append(book2_id);books.AppendChild(book2);//4.2 给根节点,添加对应的子节点XmlElement book2_name = xml.CreateElement("Name");//给子节点赋值book2_name.InnerText = "水浒传";book2.AppendChild(book2_name);//4.2 给根节点,添加对应的子节点XmlElement book2_author = xml.CreateElement("Author");//给子节点赋值book2_author.InnerText = "潘金莲";book2.AppendChild(book2_author);//4.2 给根节点,添加对应的子节点XmlElement book2_price = xml.CreateElement("Price");//给子节点赋值book2_price.InnerText = "20";book2.AppendChild(book2_price);xml.Save("Books.xml");Console.WriteLine("保存OK");Console.ReadKey();}}

对XML增删改查

    internal class Program{static void Main(string[] args){List<Person> listPerson = new List<Person>();listPerson.AddRange(new Person[] {new Person() {Name= "张三",Age=19,Gender='男' },new Person() {Name= "李四",Age=20,Gender='女' },new Person() {Name= "王五",Age=21,Gender='中' }});//把集合中的数据,写入到xml文档中//1、创建文档对象XmlDocument doc = new XmlDocument();//2、创建文档声明XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", "utf-8", null);doc.AppendChild(dec);//3、创建根节点XmlElement xmlPersons = doc.CreateElement("Persons");doc.AppendChild(xmlPersons);int i = 0;//4、遍历泛型集合,把集合中的Person对象,以元素的形式,添加到XML文档中foreach (var item in listPerson){i++;//4.1 每一个Person对象,都是一个节点XmlElement person = doc.CreateElement("Person");XmlAttribute att = doc.CreateAttribute("ID");att.Value = i.ToString();person.Attributes.Append(att);//4.2 把创建的子节点,添加到根节点上xmlPersons.AppendChild(person);//4.3 给子节点,添加对应的Name、Age、GenderXmlElement name = doc.CreateElement("Name");name.InnerText = item.Name;//4.4 把子节点Name,添加到根节点Person上person.AppendChild(name);//4.3 给子节点,添加对应的Name、Age、GenderXmlElement age = doc.CreateElement("Age");age.InnerText = item.Age.ToString();//4.4 把子节点Name,添加到根节点Person上person.AppendChild(age);//4.3 给子节点,添加对应的Name、Age、GenderXmlElement gender = doc.CreateElement("Gender");gender.InnerText = item.Gender.ToString();//4.4 把子节点Name,添加到根节点Person上person.AppendChild(gender);}doc.Save("Person.xml");Console.WriteLine("保存成功");Console.ReadKey();}}class Person{public string Name { get; set; }public int Age { get; set; }public char Gender { get; set; }}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/483414.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于springboot+vue的B2B平台的购物推荐网站(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

(每日持续更新)jdk api之ObjectOutputStream.PutField基础、应用、实战

博主18年的互联网软件开发经验&#xff0c;从一名程序员小白逐步成为了一名架构师&#xff0c;我想通过平台将经验分享给大家&#xff0c;因此博主每天会在各个大牛网站点赞量超高的博客等寻找该技术栈的资料结合自己的经验&#xff0c;晚上进行用心精简、整理、总结、定稿&…

速卖通跨境智星批量注册账号所需要的资源介绍

在寻找批量注册速卖通买家账号的道路上&#xff0c;我们发现了一个强大的工具——速卖通跨境智星。但在使用它之前&#xff0c;我们需要准备以下关键资源&#xff1a; 邮箱&#xff1a;注册买家号必不可少的资源之一。我们推荐使用国外的邮箱服务&#xff0c;比如outlook、Hot…

06 flink 的各个角色的交互

前言 这里主要是 涉及到 flink 中各个角色的交互 TaskManager 和 ResourceManager 的交互 JobMaster 和 ResourceManager 的交互 等等流程 TaskManager 和 ResourceManager 的交互 主要是 包含了几个部分, 如下, 几个菜单 TaskManager向 ResourceManager 注册 Resou…

c#创建安装windows服务

背景:最近在做设备数据对接采集时,遇到一些设备不是标准的Service-Client接口,导致采集的数据不够准确;比如设备如果中途开关机后,加工的数量就会从0开始重新计数,因此需要实时监控设备的数据,进行叠加处理;考略到工厂设备比较多,实时监听接口的数据为每秒3次,因此将…

Spring Boot中实现列表数据导出为Excel文件

点击下载《Spring Boot中实现列表数据导出为Excel文件》 1. 前言 本文将详细介绍在Spring Boot框架中如何将列表数据导出为Excel文件。我们将通过Apache POI库来实现这一功能&#xff0c;并解释其背后的原理、提供完整的流程和步骤&#xff0c;以及带有详细注释的代码示例。最…

centos 9 编译安装 LAMP wordpress

[rootlocalhost ~]# ll 总用量 655760 -rw-------. 1 root root 1040 2月 17 16:57 anaconda-ks.cfg drwxr-xr-x. 29 501 games 4096 2月 21 11:00 apr-1.7.4 -rw-r--r--. 1 root root 1122147 2月 21 10:57 apr-1.7.4.tar.gz drwxr-xr-x. 21 501 games …

动态规划记忆化搜索之滑雪

给定一个 R 行 C 列的矩阵&#xff0c;表示一个矩形网格滑雪场。 矩阵中第 i 行第 j 列的点表示滑雪场的第 i 行第 j 列区域的高度。 一个人从滑雪场中的某个区域内出发&#xff0c;每次可以向上下左右任意一个方向滑动一个单位距离。 当然&#xff0c;一个人能够滑动到某相…

【day02】每天三道 java后端面试题:Java、C++和Go的区别 | Redis的特点和应用场景 | 计算机网络七层模型

文章目录 1. Java、C和 Go 语言的区别&#xff0c;各自的优缺点&#xff1f;2. 什么是Redis&#xff1f;Redis 有哪些特点&#xff1f; Redis有哪些常见的应用场景&#xff1f;3. 简述计算机网络七层模型和各自的作用&#xff1f; 1. Java、C和 Go 语言的区别&#xff0c;各自的…

【免费雾锁王国】2024年新手搭建雾锁王国服务器教程

免费自建雾锁王国Enshrouded服务器&#xff0c;先领取阿里云300元无门槛代金券&#xff0c;然后在雾锁王国Enshrouded专题页一键部署&#xff0c;不需要基础&#xff0c;鼠标点选即可10秒钟创建一台雾锁王国游戏服务器&#xff0c;超简单&#xff0c;阿里云服务器网aliyunfuwuq…

vulfocus靶场搭建

vulfocus靶场搭建 什么是vulfocus搭建教程靶场配置场景靶场编排靶场优化 什么是vulfocus Vulfocus 是一个漏洞集成平台&#xff0c;将漏洞环境 docker 镜像&#xff0c;放入即可使用&#xff0c;开箱即用&#xff0c;我们可以通过搭建该靶场&#xff0c;简单方便地复现一些框架…

简单理解VQGAN

简单理解VQGAN TL; DR&#xff1a;与 VQVAE 类似&#xff0c;隐层压缩表征自回归生成的两阶段图像生成方法。增加感知损失和对抗损失&#xff0c;提高压缩表征模型解码出图片的清晰度。还可以通过编码并预置条件表征&#xff0c;实现条件生成。 隐层压缩表征自回归生成&#…