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,一经查实,立即删除!

相关文章

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

设计模式浅析(六) 命令模式 日常叨逼叨 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…

社区分享|中华保险基于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.…

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

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

angular-引用本地json文件

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

问题: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…

蓝桥杯嵌入式第12届真题(完成) STM32G431

蓝桥杯嵌入式第12届真题(完成) STM32G431 题目 程序 main.c /* USER CODE BEGIN Header */ /********************************************************************************* file : main.c* brief : Main program body**************************…

Linux常见的指令

目录 01. ls 指令02. pwd命令03. cd 指令04. touch指令05.mkdir指令&#xff08;重要&#xff09;&#xff1a;06.rmdir指令 && rm 指令&#xff08;重要&#xff09;&#xff1a;07.man指令&#xff08;重要&#xff09;&#xff1a;08.cp指令&#xff08;重要&#x…

浅谈maven的生命周期

正文: 在Maven中,生命周期定义了项目构建过程的不同阶段以及在每个阶段中执行的插件目标。Maven的生命周期是由一系列阶段组成的,每个阶段都有一个唯一的标识符。 Clean生命周期:用于清理项目的构建目录。它包含以下阶段: pre-clean:执行在清理操作之前的任何操作。clea…

【Vuforia+Unity】AR05-实物3D模型识别功能实现

对于3D物体的识别&#xff0c;可以是虚拟的也可以是实物的&#xff0c;但是对于虚拟的三维模型意义不大&#xff0c;我们完全可以把三维模型放在屏幕上截一张图&#xff0c;以图片识别的方式召唤数字内容&#xff0c;不过在虚拟现实中或许有用。 因此本文探讨的技术路线主要是…

【云原生】Docker consul的容器服务更新与发现

目录 什么是服务注册与发现 什么是consul consul提供的一些关键特性&#xff1a; consul 部署 consul服务器 1. 建立 Consul 服务 设置代理&#xff0c;在后台启动 consul 服务端 2. 查看集群信息 查看members状态 查看集群状态 3. 通过 http api 获取集群信息 regi…

vue-router 三级路由,路由跳转页面异常白屏或404,或刷新三级路由页面后一级和二级路由菜单丢失

问题描述 情况1. vue-router 定义三级路由&#xff0c;路由跳转了&#xff0c;页面404或者白屏情况2. 点击菜单三级路由后&#xff0c;刷新页面后一级和二级路由菜单丢失 解决方案&#xff1a; 某些时候是因为二级和三级的路由共用router-view&#xff0c;可以使用router-vi…

搭建SQL 注入平台

sqli-labs是一款学习SQL 注入的开源平台&#xff0c;共有75种不同类型的注入&#xff0c;在本书 的同步网站下载完压缩包后并解压&#xff0c;复制源码然后将其粘贴到网站的目录中&#xff0c;进入 MySQL 管理中的phpMyAdmin, 打开http://127.0.0.1/phpMyAdmin/, 在数据库…