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.mzph.cn/news/694817.shtml

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

相关文章

2024-02-21 算法: 测试链表是否有环

点击 <C 语言编程核心突破> 快速C语言入门 算法: 测试链表是否有环 前言一、双指针 ( 快慢指针 )二、代码总结 前言 要解决问题: 一道简单的算法题, 测试链表是否含有环. 想到的思路: 哈希表, 将链表指针强制转换为整型, 利用求余法建立哈希函数. 太复杂, 内存效率不高…

MyBatis的注解式开发

MyBatis的注解式开发 一、准备开发环境1.添加依赖2.jdbc.properties3.mybatis-config.xml4.Article实体类5.SqlSessionUtil工具类 二、Insert三、Delete四、Update五、Select mybatis 中也提供了注解式开发⽅式&#xff0c;采⽤注解可以减少 Sql 映射⽂件的配置。使⽤注解式开发…

设计模式浅析(六) ·命令模式

设计模式浅析(六) 命令模式 日常叨逼叨 java设计模式浅析&#xff0c;如果觉得对你有帮助&#xff0c;记得一键三连&#xff0c;谢谢各位观众老爷&#x1f601;&#x1f601; 命令模式 概念 命令模式&#xff08;Command Pattern&#xff09;是一种行为设计模式&#xff0c…

YOLOv5代码解读[02] models/yolov5l.yaml文件解析

文章目录 YOLOv5代码解读[02] models/yolov5l.yaml文件解析yolov5l.yaml文件检测头1--->耦合头检测头2--->解耦头检测头3--->ASFF检测头Model类解析parse_model函数 YOLOv5代码解读[02] models/yolov5l.yaml文件解析 yolov5l.yaml文件 # YOLOv5 &#x1f680; by Ult…

FPGA SERDESE2 (SDR收发仿真)

高速 Serdes 环路测试 高速串行通信优势非常巨大,只需要很少的IO引脚就可以实现高速通信,这也是当今FPGA高速接口的核心 技术。比如XILINX的7代FPGA,GTX可以达到10.3125Gbps,ultrascale FPGA的GTH可以达到16Gbps。目前国产FPGA还难以达到这么高的接口速度。 高速串行通信经…

社区分享|中华保险基于MeterSphere开展接口自动化测试

中华联合保险集团股份有限公司&#xff08;以下简称为“中华保险”&#xff09;始创于1986年&#xff0c;是全国唯一一家以“中华”冠名的国有控股保险公司。截至2022年12月底&#xff0c;中华保险总资产为1006.06亿元&#xff0c;在全国拥有超过2900个营业网点&#xff0c;员工…

Servlet中的请求与响应

Request和Response 1.Request和Response的概述2.Request对象2.1 Request继承体系2.2 Request获取请求数据2.3 解决post请求乱码问题 *2.4 Request请求转发(-&#xff0c;*)2.5 request的生命周期 3.HTTP响应详解(理解)1.使用抓包查看响应报文协议内容2.HTTP响应报文协议介绍 4.…

汇编英文全称

mov move mvn Mov Negative ldr LoaD Register str Store Register lsl Logic Shift Left lsr Logic Shift Right asr Arithmetic Shift Right 算数右移 ror Rotate right 循环右移…

人工智能讲师AI讲师大模型讲师叶梓介绍及大语言模型技术原理与实践提纲

叶梓&#xff0c;上海交通大学计算机专业博士毕业&#xff0c;高级工程师。主研方向&#xff1a;数据挖掘、机器学习、人工智能。历任国内知名上市IT企业的AI技术总监、资深技术专家&#xff0c;市级行业大数据平台技术负责人。 长期负责城市信息化智能平台的建设工作&#xff…

angular-引用本地json文件

angular-引用json文件&#xff0c;本地模拟数据时使用 在assets目录下存放json文件 大佬们的说法是&#xff1a;angular配置限定了资源文件的所在地&#xff08;就是assets的路径&#xff09;&#xff0c;放在其他文件夹中&#xff0c;angular在编译过程中会忽略&#xff0c;会…

云计算的两地三中心和灾备介绍

两地三中心是指在不同的地理位置建立两个数据中心和一个灾备中心&#xff0c;其中一个数据中心为主数据中心&#xff0c;另一个数据中心为备用数据中心&#xff0c;灾备中心则用于备份数据和在主数据中心或备用数据中心发生故障或灾难时提供应急支持。 异地灾备则是指在不同的地…

Docker之查看并获取最新Ubuntu镜像(十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

基于springboot+vue的教学资源库系统(前后端分离)

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

Nginx配置组成与性能调优

目录 一、Nginx配置介绍 1. 模块组成 2. 图示 3. 相关框架 二. 配置调优 1. 全局配置 1.1 关闭版本和修改版本 1.2 修改启动的进程数 1.3 cpu与work进程绑定 1.4 pid路径 1.5 nginx进程的优先级&#xff08;work进程的优先级&#xff09; 1.6 调试work进程打开的文…

利用System.Web.HttpRuntime.Cache制作缓存工具类

用到的依赖介绍 当谈到 ASP.NET 中的缓存管理时&#xff0c;常涉及到以下三个类&#xff1a;CacheDependency、HttpRuntime.Cache 和 System.Web.Caching。 CacheDependency&#xff08;缓存依赖项&#xff09;&#xff1a; CacheDependency 类用于指定一个或多个文件或目录作…

问题:Spark SQL 读不到 Flink 写入 Hudi 表的新数据,打开新 Session 才可见

博主历时三年精心创作的《大数据平台架构与原型实现&#xff1a;数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行&#xff0c;点击《重磅推荐&#xff1a;建大数据平台太难了&#xff01;给我发个工程原型吧&#xff01;》了解图书详情&#xff0c;…

Predis Multi-Zone

A Data Flow Framework with High Throughput and Low Latency for Permissioned Blockchains 联盟链的吞吐瓶颈由共识层和网络层的数据分发过程共同决定。 Predis 协议利用了共识节点的空闲带宽&#xff0c;提前分发区块中的内容即bundle&#xff0c;减少了共识区块中的内容&…

在vue3中使用canvas实现雨滴效果

在vue3中使用canvas实现雨滴效果 这是封装的一个组件DotAndRain&#xff08; &#xff09; <script setup> import { ref, onMounted } from "vue"; import { onUnmounted } from "vue";let animationFrameId null;const el ref(null); let canv…

5 原型模式 Prototype

1.模式定义: 指原型实例指定创建对象的种类&#xff0c;并且通过拷贝这些原型创建新的对象 2.应用场景&#xff1a; 当代码不应该依赖于需要复制的对象的具体类时&#xff0c;请使用Prototype模式。 Spring源码中的应用 org.springframework.beans.factory.support.AbstractB…

QT 如何让多语言翻译变得简单,提高效率?

一.QT多语言如何翻译的? 在QT的多语言翻译过程中,分为两个步骤:第一步生成ts文件,第二步将ts文件翻译为qm文件。如果我们在需要多语言的情况下,qml经常使用qstr或者qwidget中使用tr等等,遍布许多个文件夹,在需要更新新的翻译时会很麻烦。整个工程收索并修改,效率十分低…