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://xiahunao.cn/news/2799387.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

部署安装有道QanyThing

前提条件&#xff1a; 1、win10系统更新到最新的版本&#xff0c;系统版本最好为专业版本 winver 查看系统版本&#xff0c;内部版本要大于19045 2、CPU开启虚拟化 3、开启虚拟化功能&#xff0c;1、2、3每步完成后均需要重启电脑&#xff1b; 注&#xff1a;windows 虚拟…

(done) 如何判断一个矩阵是否可逆?

参考视频&#xff1a;https://www.bilibili.com/video/BV15H4y1y737/?spm_id_from333.337.search-card.all.click&vd_source7a1a0bc74158c6993c7355c5490fc600 这个视频里还暗含了一些引理 1.若 AX XB 且 X 和 A,B 同阶可逆&#xff0c;那么 A 和 B 相似。原因&#xff1…

Redis 工具类 与 Redis 布隆过滤器

Redis 工具类 1. 核心依赖 <!--redis--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency><groupId>com.google.guava…

如何修改docker容器的端口映射

要修改 Docker 容器的端口映射&#xff0c;你需要停止并删除现有的容器&#xff0c;然后使用新的端口映射重新运行容器。以下是详细步骤&#xff1a; 停止容器&#xff1a; 使用 docker stop 命令停止正在运行的容器。替换 <container_id> 为你要停止的容器的 ID 或者容器…

Python3零基础教程之Python解释器与开发环境搭建

大家好&#xff0c;我是千与编程&#xff0c;硕士毕业于北京大学&#xff0c;曾先后就职于字节跳动&#xff0c;京东等互联网大厂&#xff0c;目前在编程导航知识星球担任星球嘉宾&#xff0c;著有《AI算法毕设智囊袋》&#xff0c;《保姆级带你通关秋招教程》两大专栏。 今天开…

AndroidStudio 2024-2-21 Win10/11最新安装配置(Ktlion快速构建配置,gradle镜像源)

AndroidStudio 2024 Win10/11最新安装配置 教程目的&#xff1a; (从安装到卸载) &#xff0c;针对Kotlin开发配置&#xff0c;gradle-8.2-src/bin下载慢&#xff0c;以及Kotlin构建慢的解决 好久没玩AS了,下载发现装个AS很麻烦,就觉得有必要出个教程了(就是记录一下:嘻嘻) 因…

Java Web演化史:从Servlet到SpringBoot的技术进程及未来趋势

引言 在快速演进的IT世界里&#xff0c;Java Web开发始终屹立不倒&#xff0c;它不仅承担着历史的厚重&#xff0c;也始终面向未来。 自诞生之日起&#xff0c;Java Web技术就在不断地进化&#xff0c;以适应不同时代的需求。 本文将回顾Java Web开发的重要里程碑&#xff0c;…

Linux环境安装Git(详细图文)

说明 此文档Linux环境为&#xff1a;Ubuntu 22.04&#xff0c;本文档介绍两种安装方式&#xff0c;一种是服务器能联网的情况通过yum或apt命令下载&#xff0c;第二种采用源码方式安装。 一、yum/apt方式安装 1.yum方式安装Git 如果你的服务器环境是centos/redhot&#xff…

js谐音梗创意小游戏《望子成龙》

&#x1f33b; 前言 龙年到来&#xff0c;祥瑞满天。愿您如龙般矫健&#xff0c;事业腾飞&#xff1b;如龙鳞闪耀&#xff0c;生活美满。祝您龙年大吉&#xff0c;万事如意&#xff01; 龙年伊始&#xff0c;我给各位设计了一款原创的小游戏&#xff0c;话不多说&#xff0c;直…

B端系统:工作台页面,如何从平庸走向出众

Hi&#xff0c;大家好&#xff0c;我是贝格前端工场&#xff0c;从事8年前端开发的老司机。大家看过很多平庸的工作台页面&#xff0c;但是仔细分析过平庸的表现吗&#xff0c;仔细思考过如何实现出众的效果吗&#xff1f;这篇文章为你解读。 一、工作台页面是什么&#xff0c;…

小迪安全29WEB 攻防-通用漏洞SQL 注入增删改查盲注延时布尔报错

#知识点&#xff1a; 1、明确查询方式注入 Payload 2、明确查询方式注入产生功能 3、明确 SQL 盲注延时&布尔&报错 #详细点&#xff1a; 盲注就是在注入过程中&#xff0c;获取的数据不能回显至前端页面。 也就是在代码中无echo将sql结果输出出来 此时&#…

css4浮动+清除浮动

浮动 一.常见网页布局1.三种布局方式2.布局准则 二.浮动&#xff08;float&#xff09;1.好处2.概念3.三大特性4.使用5.常见网页布局模板6.注意点 三.清除浮动1.why2.本质3.语法4.四种way&#xff08;后三个都是给父级添加&#xff09;清除浮动总结 一.常见网页布局 1.三种布局…

【elasticsearch实战】知识库文件系统检索工具FSCrawler

需求背景 最近有一个需求需要建设一个知识库文档检索系统&#xff0c;这些知识库物料附件的文档居多&#xff0c;有较多文档格式如&#xff1a;PDF, Open Office, MS Office等&#xff0c;需要将这些格式的文件转化成文本格式&#xff0c;写入elasticsearch 的全文检索索引&am…

http协议工具:apache详解

目录 一、常见的http服务程序 1、 Apache HTTP Server 介绍 1.1 apache 概念 1.2 apache 功能 1.3 apache 特性 2、MPM&#xff08;multi-processing module&#xff09;工作模式 2.1 prefork 2.2 worker 2.3 event 二、Apache HTTP Server安装和相关文件 1、安装方…

WPF 启动项目 Grid、StackPanel 布局

WPF 启动项目 <!--x:Class"WPF_Study.App" 对应类&#xff1a;WPF_Study.App--> <!--xmlns:local"clr-namespace:WPF_Study" 命名空间&#xff1a;WPF_Study--> <Application x:Class"WPF_Study.App"xmlns"http://schema…

Centos stream9 环境使用脚本部署LAMP,实现wordpress

本人将所需要的rpm包都下载完成之后&#xff0c;直接使用脚本的形式安装。 如果需要自己下载rpm包的话&#xff0c;请下载如下包 yum install -y libxml2-devel \ tar \ gcc \ expat-devel \ bzip2-devel \ pcre-devel \ openssl-devel \ perl-devel \ sqlite-devel \ libcur…

CS_Smb_Beacon上线不出网机器

当我们想上线不出网的机器的时候&#xff0c;我们可以通过上传工具来实现&#xff0c;但是有没有不用上传工具的方法呢&#xff1f;&#xff1f;&#xff1f; 有&#xff01;&#xff01;&#xff01; 而且cs会自带&#xff01;&#xff01;&#xff01; 1.基础的网络拓扑 以下…

抽象工厂模式 Abstract Factory

1.模式定义: 提供一个创建一系列相关或互相依赖对象的接口&#xff0c;而无需指定它们具体的类 2. 应用场景: 程序需要处理不同系列的相关产品&#xff0c;但是您不希望它依赖于这些产品的 具体类时&#xff0c; 可以使用抽象工厂 3.优点: 1.可以确信你从工厂得到的产品彼…

nuxt项目搭建

1.先下载nuxt脚手架 yarn create nuxt-app <项目名>&#xff0c;记得安装完项目&#xff0c;npm i,下载node包 目录介绍 components 存放组件分别是头部&#xff08;包含导航&#xff09;和底部 layouts 页面布局&#xff0c;实现一个页面整体架构规则&#xff0c;头…

读书笔记-增强型分析:AI驱动的数据分析、业务决策与案例实践

目录 前言 运用人工智能技术&#xff0c;可以使人类社会变得更美好。人们总是期待产品更适合、服务更贴心、生活更便利。在实践中&#xff0c;技术给企业赋能&#xff0c;企业通过优质的产品和服务满足社会&#xff0c;提升人类福祉。很多金融企业已经开始尝试向潜在客户推送…