#Day01 2024.05.10 今日总结:
什么是索引器,怎么用
语法糖foreach的底层原理
泛型的学习
委托
Lambda
委托实例—窗体传值
索引器
数组或者集合内部默认就有索引器(C#),因此我们才可以默认使用【下标】的形式,访问他们中内部的某一元素
但是,我们自己定义的普通类中,默认是没有索引器的,如果我们想使用索引/下标的形式,访问对象集合中的某一元素则需要我们自己给类定义一个索引器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 索引器{ internal class Program { static void Main (string [] args ) { Student student = new Student(); Console.WriteLine(student[1 ]); Console.WriteLine(student["张三" ]); Console.ReadKey(); } } class Student { private string [] _studentNames = { "周杰伦" , "林俊杰" , "伍佰" , "凤凰传奇" , "迈克尔杰克逊" }; public string this [int Index] { get { return _studentNames[Index]; } set { _studentNames[Index] = value ; } } private Dictionary<string , int > DicStudent = new Dictionary<string , int >(); public int this [string str] { get { return DicStudent[str]; } set { DicStudent[str] = value ; } } public Student () { DicStudent.Add("张三" , 4 ); DicStudent.Add("李四" , 3 ); DicStudent.Add("王五" , 5 ); } } }
索引器案例实写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace _02索引器案例{ internal class Program { static void Main (string [] args ) { EmpIndexor empi = new EmpIndexor(); string party = empi["张无忌" , 23 ]; if (!string .IsNullOrEmpty(party) ) { Console.WriteLine(party); } else { Console.WriteLine("查无此人!!!!!!" ); } string name = empi[14 , "蛇精" ]; if (!string .IsNullOrEmpty(name)) { Console.WriteLine(name); } else { Console.WriteLine("查无此人!!!!!!" ); } Console.ReadKey (); } } class Employee { public string Name { get ; set ; } public int ID { get ; set ; } public string Party { get ; set ; } public Employee (string name,int id,string party ) { this .Name = name; this .ID = id; this .Party = party; } } class EmpIndexor { private List<Employee> EmpList = new List<Employee>(); public string this [string name,int id] { get { for (int i = 0 ;i < EmpList.Count;i++) { if (EmpList[i].Name == name && EmpList[i].ID == id) return EmpList[i].Party; } return null ; } } public int ? this [string name,string party] { get { for (int i = 0 ;i < EmpList.Count; i++) { if (EmpList[i].Name == name && EmpList[i].Party == party) return EmpList[i].ID; } return null ; } } public string this [int ID,string party] { get { for (int i = 0 ;i < EmpList.Count;i ++) { if (EmpList[i].ID == ID && EmpList[i].Party == party) return EmpList[i].Name; } return null ; } } public EmpIndexor () { EmpList.Add(new Employee("张无忌" ,23 ,"光明顶" )); EmpList.Add(new Employee("法海" ,29 ,"佛教" )); EmpList.Add(new Employee("许仙" ,25 ,"凡人" )); EmpList.Add(new Employee("小青" ,18 ,"蛇精" )); EmpList.Add(new Employee("白素贞" ,19 ,"蛇精" )); } } }
如何实现自定义类的foreach 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 using System;using System.Collections;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace _03foreach { internal class Program { static void Main (string [] args ) { Person person = new Person(); IEnumerator itor = person.GetEnumerator(); while (itor.MoveNext()) { Console.WriteLine(itor.Current); } Console.ReadKey(); } } class Person : IEnumerable { private string [] names = { "张无忌" , "周杰伦" , "伍佰" , "张三丰" , "乔峰" }; public IEnumerator GetEnumerator () { return new PersonEnumerator(names); } } class PersonEnumerator : IEnumerator { private string [] mynames { get ; set ; } public PersonEnumerator (string [] names ) { this .mynames = names; } public object Current { get { if (i < mynames.Length) { return mynames[i]; } return null ; } } int i = -1 ; public bool MoveNext () { if (i++ + 1 < mynames.Length) { return true ; } return false ; } public void Reset () { i = -1 ; } } }
泛型的学习
泛型的应用场景非常广泛
类可以使用泛型
接口可以使用泛型
方法可以使用泛型
正因如此,泛型的约束也是重点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace _06泛型约束{ internal class Program { static void Main (string [] args ) { Person<int > person = new Person<int >(); Student<Person<int >> student = new Student<Person<int >>(); Teacher<Animal> teacher = new Teacher<Animal>(); Teacher<Bird> teacher2 = new Teacher<Bird>(); Driver<Sprraw> dirver1 = new Driver<Sprraw>(); Driver<IFlyable> driver2 = new Driver<IFlyable>(); Computer<int , IComparable> cpu = new Computer<int , IComparable>(); Computer<Bird, Animal> cpu2 = new Computer<Bird, Animal>(); } } class Person <T > where T : struct { } class Student <T > where T : class ,new (){ } class Animal { } class Bird :Animal { } class Teacher <T > : Animal { } interface IFlyable { }; class Sprraw : IFlyable { } class Driver <T > where T : IFlyable { } class Computer <T ,U > where T : U { } }
Lambda表达式
委托 委托的封装好的用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 委托{ internal class Program { static void Main (string [] args ) { Action action = () => { Console.WriteLine("此委托没有返回值" ); }; action(); Func<int , int , string > func = (n, m) => { return (n + m).ToString(); }; string s = func(100 , 89347 ); Console.WriteLine(s); Console.ReadKey(); } } }
使用委托实现窗体传值 使用委托传值需要依赖注入,一般使用的方法就是构造函数注入
Form1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;namespace _13_使用委托实现窗体传值{ public partial class Form1 : Form { public Form1 () { InitializeComponent(); } private void button1_Click (object sender, EventArgs e ) { Form2 frm2 = new Form2(textBox1.Text.Trim(),ShowMsg); frm2.Show(); } void ShowMsg (string str ) { textBox1.Text = str; } private void textBox1_TextChanged (object sender, EventArgs e ) { } private void Form1_Load (object sender, EventArgs e ) { } } }
Form2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;namespace _13_使用委托实现窗体传值{ public delegate void DelShowMsg (string str ) ; public partial class Form2 : Form { private DelShowMsg delShowMsg; private Action<string > _action; public Form2 (string str, Action<string > action ) { this ._action = action; InitializeComponent(); textBox1.Text = str; } private void button1_Click (object sender, EventArgs e ) { string str= textBox1.Text; _action(str); } private void Form2_Load (object sender, EventArgs e ) { } } }
#Day02 2024.05.11 反射常用方法
反射就是动态获取数据集的源数据
Type使用(操作类的
Assembly使用(操作数据集的
Type使用
在不创建Person对象的情况下,获取type
Type type = typeof(Person)
在创建对象的情况下,获取type
Person p = new Person()
Type type2 = p.GetType()
GetMembers()
:获取类型中所有的成员
1 2 3 4 MemberInfo[] mems = type.GetMembers(); MemberInfo[] mems = type.GetMembers(BindingFlags.Instance | BindingFlags.Nonpublic);
GetMethods()
:获取类型中所有的方法
Getparameters()
:获取类型的参数
1 2 3 4 5 6 7 8 9 10 11 12 13 MethodsInfo[] mi = type.GetMethods(); foreach (var item in mi){ Console.WriteLine(item.Name); ParameterInfo[] param = item.GetParamrters(); foreach (vae item2 in param){ Console.WritwLine(item2.parapeterType) } }
GetPropertites()
:获取类型中所有属性
1 PropertyInfo[] pros = type.getProperties();
GetConstrutors
获取类型中的构造函数
1 ConstructorInfo[] ci = type.GetConstructor();
GetFields()
:获取类型中的所有字段
1 FieldInfo[] fi = type.GetFields();
Assembly使用 Assembly.LoadFile(path)
:获取path路径下的dll文件(程序集对象
ass.GetTypes()
:获取所有自定义的类型
Activator.Greateinstance(type)
:动态地创建对象(只需要知道对象的名称)返回object
type.GetConstructor
:调用构造函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Assembily ass = Assembly.LoadFile(path); Types[] types = ass.getTypes(); Types[] types = ass.GetExportedTypes(); Type type = ass.Gettype("ClassLibrary.Person" ); MethodInfo mi = type.GetMethod("InstanceMethod" ); object o = Activator.CteateInstance(type);mi.Invoke(o,null ); MethodInfo mi = type.GetMethod("Add" ,new Type[] { typeof (int ),typeof (int )}); object o = Activator.CteateInstance(type);mi.Invoke(o,new object [] { 1 , 1 }); ConstructorInfo ci = type.GetConstructor(new type[] {}) object o = ci.Invoke(null );Consol.Writeline(o.GteType());
插件的制作 插件的制作过程如下
创建一个【解决方案文件夹】
创建窗体程序
创建规范接口文件
确定是接口还是抽象类
确定属性、方法、构造函数(抽象类才需要)
创建实现插件功能的类库
将所有的dll文件放在指定的文件夹中
Form窗体Load中实现插件功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 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;using Plug_in_Components_Rule;namespace _05_记事本插件应用程序{ public partial class Form1 : Form { public Form1 () { InitializeComponent(); } private void Form1_Load (object sender, EventArgs e ) { string path = Assembly.GetExecutingAssembly().Location; path = Path.GetDirectoryName(path); path = Path.Combine(path, "Plug_in_Componets" ); string [] filePath = Directory.GetFiles(path); foreach (string item in filePath) { Assembly ass = Assembly.LoadFile(item); Type[] types = ass.GetExportedTypes(); foreach (var item2 in types) { if (typeof (Plug_in_Rule).IsAssignableFrom(item2) && !item2.IsAbstract) { object o = Activator.CreateInstance(item2); Plug_in_Rule pir = (Plug_in_Rule)o; ToolStripItem tsi = menuStrip1.Items.Add(pir.Name); tsi.Click += Tsi_Click; tsi.Tag = pir; } } } } private void Tsi_Click (object sender, EventArgs e ) { ToolStripItem tsi = (ToolStripItem)sender; Plug_in_Rule pir = (Plug_in_Rule)tsi.Tag; pir.ChangeText(textBox1); } } }
插件开发 开发者
插件开发的规范(接口/抽象类)
单独的写一个程序读取所有的插件,把功能绑定到自己的程序中
插件开发者
照着开发的规范,实现功能的拓展
#Day03 2024.05.12 今日知识点
事件:概念、组成元素
多播委托(不安全
事件(安全
自创组件
委托、事件和反射面试必问,一定得好好总结!!!
递归
事件 概念 :事件就是一个类型安全的委托
组成元素 :
注册事件
触发事件
响应事件
多播委托 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public delegate void del () ;del d = m1; d += m2; d += m3; d += m4; d(); static void m1 { Console.WriteLine("我是m1" ); } static void m2 { Console.WriteLine("我是m2" ); } static void m3 { Console.WriteLine("我是m3" ); } static void m4 { Console.WriteLine("我是m4" ); }
事件 概念 :事件就是一个【类型安全】的委托
为什么可以用委托模拟事件使用事件和使用委托,过程是一样的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;namespace 委托模拟事件{ internal class Program { static void Main (string [] args ) { MusicPlayer mp = new MusicPlayer(); mp.BeforeMusic = () => { Console.WriteLine("1、检测该歌曲是否为会员歌曲。2、检测登录成员是否为会员。3、是否从数据库中调取歌词" ); }; mp.AfterMusic = () => { Console.WriteLine("1、 检测当前播放是什么播放模式。2、按照播放模式播放下一首歌曲。" ); }; mp.StartMusic(); mp.Stop(); Console.ReadKey(); } } class MusicPlayer { public Action BeforeMusic; public Action AfterMusic; private void Playing () { this .BeforeMusic(); Console.WriteLine("正在播放音乐。。" ); } public void StartMusic () { Console.WriteLine("开始播放音乐" ); this .Playing(); Thread.Sleep(3000 ); } public void Stop () { Console.WriteLine("结束播放音乐" ); this .AfterMusic(); } } }
自创组件
在创建类里面选择用户控件(每次更改后要重新生成
自定义
点击跳转
递归 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.IO;using System.Linq;using System.Text;using System.Threading;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 ) { } private void btn1_Click (object sender, EventArgs e ) { string path = @"E:\Aria2" ; Recursion(path, treeView1.Nodes); } private void Recursion (string path,TreeNodeCollection treeNodes ) { string [] fliePaths = Directory.GetDirectories(path); foreach (string paths in fliePaths) { TreeNode tn = treeNodes.Add(Path.GetFileName(paths)); Recursion(paths, tn.Nodes); } string [] files = Directory.GetFiles(path); foreach (string paths in files) { treeNodes.Add(Path.GetFileName(paths)); } } } }
#Day04 2024.05.14 今日知识点:
XML
正则表达式
Xml Xml文件路径默认保存在当前目录的Debug文件夹里面
第一次使用CreateElement创建的结点为根节点,其后创建的结点都为子节点
先创造属性后添加到结点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Xml;namespace ConsoleApp1 { internal class Program { static void Main (string [] args ) { XmlDocument xd = new XmlDocument(); List<Person> listPerson = new List<Person>(); listPerson.Add(new Person() { Name = "周杰伦" , Age = 98 , Gender = '男' , ID = "1" }); listPerson.Add(new Person() { Name = "林俊杰" , Age = 28 , Gender = '男' , ID = "2" }); listPerson.Add(new Person() { Name = "伍佰" , Age = 38 , Gender = '男' , ID = "3" }); listPerson.Add(new Person() { Name = "周饼伦" , Age = 48 , Gender = '男' , ID = "4" }); listPerson.Add(new Person() { Name = "王力宏" , Age = 58 , Gender = '男' , ID = "5" }); listPerson.Add(new Person() { Name = "张杰" , Age = 38 , Gender = '男' , ID = "6" }); XmlDeclaration dec = xd.CreateXmlDeclaration("1.0" , "utf-8" , null ); xd.AppendChild(dec); XmlElement Persons = xd.CreateElement("Persons" ); xd.AppendChild(Persons); foreach (Person person in listPerson) { XmlElement Person = xd.CreateElement("Person" ); Persons.AppendChild(Person); XmlAttribute att = xd.CreateAttribute("ID" ); att.Value = person.ID; Person.Attributes.Append(att); XmlElement name = xd.CreateElement("Name" ); name.InnerText = person.Name; Person.AppendChild(name); XmlElement age = xd.CreateElement("Age" ); age.InnerText = person.Age.ToString(); Person.AppendChild(age); XmlElement gender = xd.CreateElement("Gender" ); gender.InnerText = person.Gender.ToString(); Person.AppendChild(gender); } xd.Save("Profiles.xml" ); Console.WriteLine("OK" ); } } class Person { public string Name { get ; set ; } public int Age { get ; set ; } public char Gender { get ; set ; } public string ID { get ; set ; } } }
正则表达式 基础概念
.
匹配单个字符(\n除外)
[]
匹配括号里的任何一个字符
|
表示或运算
z|food为不完全匹配,所有含有z和food的字符串使用Regex.IsMatch返回都为true
(z|f)ood为不完全匹配,所有含有zood和food的字符串使用Regex.IsMatch返回都为true
^z|food$为不 完全匹配,以z开头或者以food结尾的字符串使用Regex.IsMatch返回都为true
^(z|food)$为完全匹配,只有z和food这两个字符串使用Regex.IsMatch返回为true
*
等价与{ 0 , },匹配0次或多次*号前面的单个字符
+
等价与{ 1, },匹配1次或多次+号前面的单个字符
?
等价与{ 0, 1 },匹配0次或一次?号前面的单个字符
{n}
匹配n次{}前面的单个字符或字符组
{n,m}
至少匹配n次,至多匹配m次{}前面的单个字符或字符组
^
匹配一行的开始
$
匹配一行的结束
进阶概念
\d
代表一个数字,等同于[0-9]———————–d => digital
\D
代表非数字,等同于[^0-9]
\s
代表换行符、tab制表符等空白字符 ————-s => space
\S
代表非空白字符(a0%$@等)
\w
等效于[0-9a-zA-Z]————————————w => word
\W
等同于[^\w]
\b
单词的边界,一边是单词,另一边不是单词
正则表达式用法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 match Regex.IsMatch(str, "^([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})$" ); matches string str = "June 26 , 1951 " ;MatchCollection ans = Regex.Matches(str,@"\w+" ); foreach (Match match in ans){ string a = match.Value; Console.WriteLine(a); } group static void Main (string [] args ){ string path = @"C:\Users\86159\Desktop\co.txt" ; string [] strs = File.ReadAllLines(path); foreach (string str in strs) { Match mc = Regex.Match(str, @"^(?<UserName>[A-Za-z0-9._%+-]+)@(?<yuMing>[A-Za-z0-9.-]+\.[\w]{2,})$" ); Console.WriteLine(mc.Groups["UserName" ]); Console.WriteLine(mc.Groups["yuMing" ]); } Console.ReadKey(); } replace static void Main (string [] args ){ string str = "234-----234--------------34------55" ; str = Regex.Replace(str, "-+" , "-" ); Console.WriteLine(str); Console.ReadKey(); } static void Main (string [] args ){ string str = "黑夜总会过去,光明终将到来" ; str = Regex.Replace(str, "夜总会" , "***" ); Console.WriteLine(str); Console.ReadKey(); }
贪婪匹配 1 2 3 4 5 6 7 8 9 10 11 string str = "1111。11。111。111111。" ;Match mc = Regex.Match(str, @".+。" ); Console.WriteLine(mc); Match mc2 = Regex.Match(str, @".+?。" ); Console.WriteLine(mc2); Console.ReadKey();
#Day05 2024.05.15 今日知识点:
并发-并行-同步-异步
线程方法补充
线程优先级
线程生命周期
多线程访问同一资源问题 (可见性、原子性、有序性)
死锁
单例设计模式(多线程不安全
同步方法
信号量
线程池
异步编程模型(EAP、APM、TPL)吹牛逼用的
今天内容知识前提 :主要是CPU部分
并发-并行-同步-异步
并发(Concurrency)
并发是指系统能够同时处理多个任务或多个操作的能力。这些任务可以在时间上重叠,但不一定是同时执行的。
并行(Parallelism)
并行是指系统确实同时执行多个任务或操作。在并行系统中,不同的任务在同一时刻通过不同的处理单元(比如多核处理器或分布式系统中的不同节点)进行处理。
同步(Synchronous)
同步指的是任务按照固定的顺序依次执行,每个任务都要等待上一个任务完成后才能开始执行。任务之间的关系通常是紧密耦合的。
同步通常用于需要严格控制执行顺序和任务之间相互依赖关系的场景,确保数据的一致性和正确性。
异步(Asynchronous)
异步指的是任务不必等待其他任务的完成就可以开始执行。任务之间的执行顺序可以是随机的,并且任务之间的耦合度较低。
异步通常用于需要提高系统的响应性和吞吐量,以及处理可能发生阻塞的操作(比如网络请求、文件IO等),使得系统能够继续执行其他任务而不必等待阻塞操作完成。
线程方法补充 1 2 3 4 5 6 7 8 Thread th = new Thread( () => { Console.WriteLine("新线程方法补充" ); Console.WriteLine("这三个方法是调试使用的,一般程序里最好不要使用" ); } ); 1 、Thread.Sleep(t);使当前线程睡眠t毫秒2 、Thread.Join();使用以后在当前线程执行完之前,其余的线程被阻塞无法执行3 、Thread.Suspend();挂起队列,也就是可以是当前线程暂停。可以使用Thread.Resume()解除挂起状态
线程优先级 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 static void Main (string [] args ){ int num = 0 ; Thread th1 = new Thread(() =>{ while (true ) { num++; } }); int cnt = 0 ; Thread th2 = new Thread(() =>{ while (true ) { cnt++; } }); th1.Start(); th2.Start(); th1.Priority = ThreadPriority.Highest; th2.Priority = ThreadPriority.Lowest; Thread.Sleep(100 ); Console.WriteLine(num); Console.WriteLine(cnt); Console.ReadKey(); }
线程的生命周期
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 static void Main (string [] args ){ Thread th = new Thread(() => { Console.WriteLine("已经开始执行线程啦" ); Thread.Sleep(1000 ); for (int i = 0 ; i < 10 ; i++) { Console.WriteLine(i); } }); Console.WriteLine(th.ThreadState); th.Start(); Console.WriteLine(th.ThreadState); while (true ) { if (th.ThreadState == ThreadState.WaitSleepJoin) { Console.WriteLine("线程进入睡眠了" ); break ; } } }
多线程访问同一资源
可见性
原子性
有序性
volatile解决了可见性和有序性,具体体现在这两方面:
多线程缓存更新同步 :volatile
关键字确保了当一个线程更新了 volatile
字段的值后,其他线程立即能够看到这个更新,而不是使用自己线程的缓存中的旧值。
指令重排序禁止 :volatile
关键字禁止了编译器和处理器对标记为 volatile
的字段进行指令重排序,这样可以保证程序执行的顺序性,避免了可能的程序错误。
保证原子性则需要使用“锁”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 static volatile int number = 0 ;static object o = new object ();static void Main (string [] args ){ Thread th1 = new Thread(() => { for (int i = 0 ; i < 10000 ; i++) { Interlocked.Increment(ref number); Thread.Sleep(0 ); } }); Thread th2 = new Thread(() => { for (int i = 0 ; i < 10000 ; i++) { Interlocked.Increment(ref number); Thread.Sleep(0 ); } }); th1.Start(); th2.Start(); Thread.Sleep(2000 ); Console.WriteLine(number); Console.ReadKey(); }
死锁 造成死锁的四个条件(老生常谈,背就行了)
互斥条件
不可抢占条件
申请和占有条件
循环等待条件
单例设计模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;namespace 单例设计模式{ internal class Program { static void Main (string [] args ) { for (int i = 0 ;i < 10 ;i ++) { Thread th = new Thread( () => { SinglePerson sp = SinglePerson.GetSinglePerson(); Thread.Sleep(0 ); Console.WriteLine(sp.GetHashCode()); }); th.Start(); } Console.ReadKey(); } } class SinglePerson { private SinglePerson () { } private static SinglePerson _singlePerson = new SinglePerson(); private static object o = new object (); public static SinglePerson GetSinglePerson () { return _singlePerson; } } }
同步方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;namespace 同步方法{ internal class Program { static int num = 0 ; static void Main (string [] args ) { Thread th = new Thread(AddNumber); Thread th1 = new Thread(AddNumber); th.Start(); th1.Start(); Thread.Sleep(1000 ); Console.WriteLine(num); Console.ReadKey (); } static void AddNumber () { for (int i = 0 ; i < 10000 ; i++) { num++; Thread.Sleep (0 ); } } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 using System;using System.Collections.Generic;using System.Linq;using System.Runtime.CompilerServices;using System.Text;using System.Threading;using System.Threading.Tasks;namespace 同步方法{ internal class Program { static int num = 0 ; static void Main (string [] args ) { Thread th = new Thread(AddNumber); Thread th1 = new Thread(AddNumber); th.Start(); th1.Start(); Thread.Sleep(1000 ); Console.WriteLine(num); Console.ReadKey (); } [MethodImpl(MethodImplOptions.Synchronized) ] static void AddNumber () { for (int i = 0 ; i < 10000 ; i++) { num++; Thread.Sleep (0 ); } } } }
信号量
与操作系统中的信号量有区别
C#中信号量可以理解成信号灯
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 static void Main (string [] args ){ AutoResetEvent mre = new AutoResetEvent(false ); Thread th = new Thread(() => { while (true ) { Console.WriteLine("前方是红灯,不要执行线程!!!" ); Thread.Sleep(1000 ); mre.Set(); mre.WaitOne(); Console.WriteLine("看见这条信息就说明变绿灯了" ); } }); th.Start(); Console.WriteLine("前方停止三秒钟" ); Thread.Sleep(3000 ); Console.ReadKey(); }
线程池
多线程——->线程池——->三种异步编程——->async和await
线程池的缺点就是无法对目标线程进行操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;namespace 线程池{ internal class Program { static void Main (string [] args ) { for (int i = 0 ;i < 10 ;i ++) { Thread th = new Thread(() => { Console.WriteLine("这是我创建的线程,ID是:" + Thread.CurrentThread.ManagedThreadId); }); th.Start(); } for (int i = 0 ;i < 10 ;i ++) { ThreadPool.QueueUserWorkItem((o) => { Console.WriteLine("这是线程池创建的线程,ID是:" + Thread.CurrentThread.ManagedThreadId); }); } Console.ReadKey(); } } }
事件编程模型(吹牛逼用的) EAP事件编程(了解) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 static void Main (string [] args ){ WebClient wc = new WebClient(); wc.DownloadStringCompleted += Wc_DownloadStringCompleted; wc.DownloadStringAsync(new Uri("http://www.svipclass.com" )); for (int i = 0 ; i < 20 ; i++) { Console.WriteLine("Hello World" ); } Console.ReadKey(); Console.ReadKey(); } private static void Wc_DownloadStringCompleted (object sender, DownloadStringCompletedEventArgs e ){ Console.WriteLine(e.Result); }
APM事件编程(了解) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 string path = @"C:\Users\ThinkPad\Desktop\餐饮项目开发步骤.txt" ;using (FileStream fsRead = new FileStream(path, FileMode.Open, FileAccess.Read)){ byte [] buffer = new byte [1024 * 1024 ]; IAsyncResult asyncResult = fsRead.BeginRead(buffer, 0 , buffer.Length, null , null ); asyncResult.AsyncWaitHandle.WaitOne(); int r = fsRead.EndRead(asyncResult); string str = Encoding.UTF8.GetString(buffer, 0 , r); Console.WriteLine(str); } Console.ReadKey();
TPL事件编程(最简单的await和async)一定带掌握
异步方法的返回值必须是Task的泛型。int–Task void — Task
异步方法必须被标记为async
异步方法有传染性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 static async Task Main (string [] args ){ int length = await GetDownloadStr("https://www.baidu.com" , @"C:\Users\86159\Desktop\cxxxx.txt" ); Console.WriteLine(length); Console.ReadKey(); } static async Task<int > GetDownloadStr (string url, string path ){ WebClient wc = new WebClient(); string s = await wc.DownloadStringTaskAsync(url); Console.WriteLine(s); using (FileStream fsWrite = new FileStream(path, FileMode.Create, FileAccess.Write)) { byte [] buffer = Encoding.UTF8.GetBytes(s); await fsWrite.WriteAsync(buffer, 0 , buffer.Length); } return s.Length; }
#Day06-07 2024.05.16-2024.05.17
设计原则(面向抽象编程) 写类的设计第一件事就是封装变化。
-降低耦合度
继承的问题(以后尽量不要使用继承)
-1、破坏了系统的封装性,基类发生了改变,子类的实现也会发生改变,子类的实现也会发生改变。 -2、子类如果不需要父类的某一方法,则系统耦合度变高。 -3、继承是静态的,不能在程序运行时发生改变
类与类之间的关系
-泛化、实现、组合、聚合、关联、依赖
1、单一职责原则(SRP)
首先也是最重要的,想要实现高内聚低耦合必须遵守的原则。
条例
应该有且只有一个引起类变更的原因(一个类只负责一件事儿)
好处
提高代码的可读性,提高系统的可维护性
降低类的复杂性,一个模块只负责一个人职责,提高系统的可拓展性和可维护性
降低变更引起的风险,变更时必然的,如果单一职责做得好,当修改一个功能的时候可以显著的降低对另一个功能的影响。
2、开放封闭原则(OCP)
开放封闭原则是 是面向对象设计的终极目标,而依赖倒置原则 是实现开放封闭原则 的的基础
如果开放封闭原则 是设计大楼的蓝图,那么依赖倒置原则 就是大楼的钢铁架构
条例
开放封闭原则是面向对象所有原则的核心。
需求改变时,在不改变实体源代码接(类、接口、方法等)的前提下,通过拓展功能,使其满足新的需求。
3、依赖倒置原则(DIP) 条例
高层模块不应该依赖于底层模块,两个都应该依赖于抽象
抽象不应该依赖于细节,细节应该依赖于抽象
依赖倒置原则 的本质就是通过抽象(接口或抽象类)是各个类和模块的实现彼此独立,互不影响,实现模块间的松耦合
4、里式替换原则(LSP) 条例
如果S是T的子类型,则T类型的对象可以替换为S类型的对象
所有引用父类对象的地方,都可以使用其子类型代替
子类可以替代父类
5、接口分离原则(ISP) 条例
客户端不应该依赖它不需要的接口
一个类对另一个类的依赖应该建立在最小接口上
接口尽量细分,不要在一个接口中放很多种方法
6、合成复用原则(CRP) 条例
又称组合/聚合复用原则
尽量使用对象组合,而不是继承达到复用
如何实现?
7、迪米特原则(TLKP/DP)
和直接朋友通信
成员对象(属性、字段)
方法参数
方法返回值
条例
它要求一个对象应该对其他对象有最少的了解
降低类之间的耦合
迪米特原则实际上就是一个类在创建方法和属性时要遵守的法则
设计原则总结
#Day08 - 09 2024.05.18 - 25
说一下你对深拷贝和浅拷贝的理解
1、单例设计模式 2、简单工厂设计模式
简单工厂:一个工厂类,一个产品抽象类,工厂类创建方法传入参数并判断,选择创建具体的产品对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 internal class Program { static void Main (string [] args ) { Console.WriteLine("请输入运算符" ); string oper = Console.ReadLine(); Console.WriteLine("请输入你要计算的第一个数字" ); int n1 = int .Parse(Console.ReadLine()); Console.WriteLine("请输入你要计算的第二个数字" ); int n2 = int .Parse(Console.ReadLine()); Factory CRF = new Factory(oper,n1,n2); CRF.GetResult(); Console.ReadKey(); } } class Factory { public String oper { get ; set ; } public int n1 { get ; set ; } public int n2 { get ; set ; } public Factory (String oper, int n1, int n2 ) { this .oper = oper; this .n1 = n1; this .n2 = n2; } public void GetResult () { if (oper == "+" ) { Calculator cal = new Add(n1,n2); Console.WriteLine(cal.GetResult()); } else if (oper == "-" ) { Calculator cal = new Sub(n1, n2); Console.WriteLine(cal.GetResult()); } else if (oper == "*" ) { Calculator cal = new Mul(n1, n2); Console.WriteLine(cal.GetResult()); } else if (oper == "/" ) { Calculator cal = new Div(n1, n2); Console.WriteLine(cal.GetResult()); } } } abstract class Calculator { public int n1 { get ; set ; } public int n2 { get ; set ; } public Calculator (int n,int m ) { this .n1 = n; this .n2 = m; } public abstract double GetResult () ; } class Add : Calculator { public Add (int n, int m ) : base (n, m ) { } public override double GetResult () { return this .n1 + this .n2; } } class Sub : Calculator { public Sub (int n, int m ) : base (n, m ) { } public override double GetResult () { return this .n1 - this .n2; } } class Mul : Calculator { public Mul (int n, int m ) : base (n, m ) { } public override double GetResult () { return this .n1 * this .n2; } } class Div : Calculator { public Div (int n, int m ) : base (n, m ) { } public override double GetResult () { return this .n1 / this .n2; } }
3、工厂设计模式
工厂设计模式:多个工厂类,一个产品抽象类,利用多态创建不同的产品对象,避免了大量的if-else判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 internal class Program { static void Main (string [] args ) { double result = GetResult(new AddFactory(), 10 , 20 ); Console.WriteLine(result); Console.ReadKey(); } static double GetResult (AbstractFactory af,int n1,int n2 ) { AbstractFactory factory = af; return af.GetExatCalculator(n1,n2).GetResult(); } } abstract class AbstractFactory { public abstract Calculator GetExatCalculator (int n1,int n2 ) ; } class AddFactory : AbstractFactory { public override Calculator GetExatCalculator (int n1, int n2 ) { return new Add(n1,n2); } } class SubFactory : AbstractFactory { public override Calculator GetExatCalculator (int n1, int n2 ) { return new Sub(n1, n2); } } class MulFactory : AbstractFactory { public override Calculator GetExatCalculator (int n1, int n2 ) { return new Mul(n1, n2); } } class DivFactory : AbstractFactory { public override Calculator GetExatCalculator (int n1, int n2 ) { return new Div(n1, n2); } } abstract class Calculator { public double n1 { get ; set ; } public double n2 { get ; set ; } public Calculator (double n1, double n2 ) { this .n1 = n1; this .n2 = n2; } public abstract double GetResult () ; } class Add : Calculator { public Add (int n, int m ) : base (n, m ) { } public override double GetResult () { return this .n1 + this .n2; } } class Sub : Calculator { public Sub (int n, int m ) : base (n, m ) { } public override double GetResult () { return this .n1 - this .n2; } } class Mul : Calculator { public Mul (int n, int m ) : base (n, m ) { } public override double GetResult () { return this .n1 * this .n2; } } class Div : Calculator { public Div (int n, int m ) : base (n, m ) { } public override double GetResult () { return this .n1 / this .n2; } }
4、抽象工厂设计模式(难)
抽象工厂设计模式:多个工厂类,多个产品抽象类,产品子类分组,同一工厂实现类创建同组中的不同产品,减少了工厂子类的数量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 internal class Program { static void Main (string [] args ) { IAbstractFactory factory = new DellFactory(); IScreen screen = factory.GetScreenBrand(); screen.GetBrand(); IKeyBoard keyBoard = factory.GetKeyBoardBrand(); keyBoard.GetBrand(); IMouse mouse = factory.GetMouseBrand(); mouse.GetBrand(); Console.ReadKey(); } } interface IKeyBoard { void GetBrand () ; } class DellKeyBoard : IKeyBoard { public void GetBrand () { Console.WriteLine("我是Dell键盘" ); } } class HPKeyBoard : IKeyBoard { public void GetBrand () { Console.WriteLine("我是HP键盘" ); } } interface IMouse { void GetBrand () ; } class DellMouse : IMouse { public void GetBrand () { Console.WriteLine("我是Dell鼠标" ); } } class HPMouse : IMouse { public void GetBrand () { Console.WriteLine("我是HP鼠标" ); } } interface IScreen { void GetBrand () ; } class DellScreen : IScreen { public void GetBrand () { Console.WriteLine("我是Dell屏幕" ); } } class HPScreen : IScreen { public void GetBrand () { Console.WriteLine("我是HP屏幕" ); } } interface IAbstractFactory { IMouse GetMouseBrand () ; IKeyBoard GetKeyBoardBrand () ; IScreen GetScreenBrand () ; } class DellFactory : IAbstractFactory { public IKeyBoard GetKeyBoardBrand () { return new DellKeyBoard(); } public IMouse GetMouseBrand () { return new DellMouse(); } public IScreen GetScreenBrand () { return new DellScreen(); } } class HPFactory : IAbstractFactory { public IKeyBoard GetKeyBoardBrand () { return new HPKeyBoard(); } public IMouse GetMouseBrand () { return new HPMouse(); } public IScreen GetScreenBrand () { return new HPScreen(); } }
5、原型设计模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Runtime.Serialization.Formatters.Binary;using System.Text;using System.Threading.Tasks;namespace 原型设计模式{ internal class Program { static void Main (string [] args ) { Person p = new Person(); p.Name = "周杰伦" ; p.Age = 44 ; p.Dog = new Dog { Name = "旺财" }; Person p1 = p.PeronsWiseCopy(); p1.Name = p.Name; p1.Age = p.Age; p1.Dog = p.Dog; Person p2 = p.PersonDeepCopy(p); string name = p2.Name; int age = p2.Age; Dog dog = p2.Dog; Console.WriteLine("Ok" ); Console.ReadKey (); } } [Serializable ] class Person { public string Name { get ; set ; } public int Age { get ; set ; } public Dog Dog { get ; set ; } public Person PeronsWiseCopy () { return (Person)this .MemberwiseClone(); } public Person PersonDeepCopy (Person p ) { using (MemoryStream ms = new MemoryStream()) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(ms, p); ms.Position = 0 ; return (Person)bf.Deserialize(ms); } } } [Serializable ] class Dog { public string Name { get ; set ; } } }
6、建造者设计模式(难)
创建多子类部件的对象
完整的对象,需要多个子部件对象?
完整的对象,需要几个顺序进行子部件对象的创建?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 建造者设计模式{ internal class Program { static void Main (string [] args ) { AbstractBuilder builder = new GoodComoputer(); Director dir = new Director(builder); Computer cpu = builder.GetComputer(); cpu.ShowComponent(); Console.ReadKey(); } } class Computer { List<string > parts = new List<string >(); public void SetComponent (string s ) { parts.Add(s); } public void ShowComponent () { foreach (string s in parts) { Console.WriteLine(s); } } } interface AbstractBuilder { void SetCPU () ; void SetMemory () ; void SetDisk () ; void SetPower () ; Computer GetComputer () ; } class BadComoputer : AbstractBuilder { private Computer computer = new Computer(); public Computer GetComputer () { return computer; } public void SetCPU () { computer.SetComponent("I1的CPU" ); } public void SetDisk () { computer.SetComponent("1Kb的硬盘" ); } public void SetMemory () { computer.SetComponent("1Mb的内存" ); } public void SetPower () { computer.SetComponent("1W的电源" ); } } class GoodComoputer : AbstractBuilder { private Computer computer = new Computer(); public Computer GetComputer () { return computer; } public void SetCPU () { computer.SetComponent("I700的CPU" ); } public void SetDisk () { computer.SetComponent("100Pb的硬盘" ); } public void SetMemory () { computer.SetComponent("1000G的内存" ); } public void SetPower () { computer.SetComponent("1000W的电源" ); } } class Director { public Director (AbstractBuilder ab ) { ab.SetCPU(); ab.SetDisk(); ab.SetMemory(); ab.SetPower(); } } }
7、适配器设计模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 internal class Program { static void Main (string [] args ) { ChargeAdapter adapter = new ChargeAdapter(); adapter.IPhoneCharge(); Console.ReadKey(); } } class AndroidAdaptee { public void AndroidCharge () { Console.WriteLine("使用安卓充电器充电" ); } } interface IphoneTarget { void IPhoneCharge () ; } class ChargeAdapter : IphoneTarget { private AndroidAdaptee adaptee = new AndroidAdaptee(); public void IPhoneCharge () { adaptee.AndroidCharge(); } }
8、装饰器设计模式(难)
不明白为什么要设计成对象套对象?
明白一点但没法说出来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 internal class Program { static void Main (string [] args ) { Bervage bervage = new MilkTea(); Decorater buding1 = new Buding(bervage); Decorater boba = new Boba(buding1); Decorater xiancao = new Xiancao(boba); Console.WriteLine(xiancao.GetMoney()); Console.ReadKey(); } } abstract class Bervage { public abstract double GetMoney () ; } class MilkTea : Bervage { public override double GetMoney () { Console.WriteLine("奶茶10一杯" ); return 10 ; } } class FruitTea : Bervage { public override double GetMoney () { Console.WriteLine("果茶12一杯" ); return 12 ; } } class Soda : Bervage { public override double GetMoney () { Console.WriteLine("苏打水8元一杯" ); return 8 ; } } abstract class Decorater : Bervage { protected Bervage bervage; public Decorater (Bervage bervage ) { this .bervage = bervage; } public override double GetMoney () { return this .bervage.GetMoney(); } } class Buding : Decorater { private static double money = 3 ; public Buding (Bervage bervage ) : base (bervage ) { } public override double GetMoney () { return base .GetMoney() + money; } } class Boba : Decorater { private static double money = 3.5 ; public Boba (Bervage bervage ) : base (bervage ) { } public override double GetMoney () { return base .GetMoney() + money; } } class Xiancao : Decorater { private static double money = 4 ; public Xiancao (Bervage bervage ) : base (bervage ) { } public override double GetMoney () { return base .GetMoney() + money; } }
9、代理设计模式
代理进行某些行为,有些需要权限,有些不需要(clash)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 internal class Program { static void Main (string [] args ) { ISubject subject = new Proxy(new RealSubject()); ClassFlower cf = new ClassFlower(); cf.Name = "如花" ; subject.GiveSmoking(cf); subject.GiveBeer(cf); subject.DJ(cf); Console.ReadKey(); } } class ClassFlower { public string Name { get ; set ; } } interface ISubject { void GiveSmoking (ClassFlower cf ) ; void GiveBeer (ClassFlower cf ) ; void DJ (ClassFlower cf ) ; } class RealSubject : ISubject { public void DJ (ClassFlower cf ) { Console.WriteLine("老王请" +cf.Name +"去蹦迪" ); } public void GiveBeer (ClassFlower cf ) { Console.WriteLine("老王请" +cf.Name +"喝台子" ); } public void GiveSmoking (ClassFlower cf ) { Console.WriteLine("老王请" +cf.Name+"抽华子" ); } } class Proxy : ISubject { private RealSubject _realSubject; public Proxy (RealSubject realSubject ) { this ._realSubject = realSubject; } public void DJ (ClassFlower cf ) { this ._realSubject.DJ(cf); } public void GiveBeer (ClassFlower cf ) { this ._realSubject.GiveBeer(cf); } public void GiveSmoking (ClassFlower cf ) { this ._realSubject.GiveSmoking(cf); } }
10、外观设计模式
我理解的就是极致封装,只留给使用者一个接口(将外观设计地好看)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 internal class Program { static void Main (string [] args ) { Person p = new Person(); p.PToZM(); Console.ReadKey(); } } class Person { ZWDT zwdt = new ZWDT(); public void PToZM () { zwdt.ZM(); } } class ZWDT { public void WalkToPolice () { Console.WriteLine("去派出所班出生证明" ); } public void WalkToStreet () { Console.WriteLine("去街道开具户籍证明" ); } public void WalkToShopital () { Console.WriteLine("去医院开出生证明" ); } public void ZM () { WalkToPolice(); WalkToStreet(); WalkToShopital(); } }
11、桥接设计模式
12、组合设计模式
类似于Winform中的TreeView组件(如图所示)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace _01_组合设计模式{ internal class Program { static void Main (string [] args ) { Component component = new Coposite() { Name = "华北理工大学" }; Component composite = new Coposite() { Name = "计算机软件与应用专业1班" }; Leaf leaf1 = new Leaf() { Name = "瑶瑶" }; Leaf leaf2 = new Leaf() { Name = "张峥" }; component.Add(composite); composite.Add(leaf1); composite.Add(leaf2); component.Display(4 ); Console.ReadKey(); } } abstract class Component { public string Name { get ; set ; } public abstract void Add (Component component ) ; public abstract void Remove (Component component ) ; public abstract void Display (int depth ) ; } class Coposite : Component { private List<Component> listComps = new List<Component>(); public override void Add (Component component ) { listComps.Add(component); } public override void Display (int depth ) { Console.WriteLine(new string ('-' , depth) + this .Name); foreach (var item in listComps) { item.Display(depth+4 ); } } public override void Remove (Component component ) { listComps.Remove(component); } } class Leaf : Component { public override void Add (Component component ) { } public override void Display (int depth ) { Console.WriteLine(new string ('-' , depth) + this .Name); } public override void Remove (Component component ) { } } }
13、享元设计模式
目的就是节省资源(共享单车)
享元设计模式一定得有一个享元工厂,用来管理FlyWeight对象。它主要用来确保合理的使用Flyweight,当用户请求一个FlyWeight时,FlyWeightFactory对象提供一个已创建的实例过着创建一个。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _04_享元设计模式
{
internal class Program
{
static void Main(string[] args)
{
//1、创建享元工厂
Factory factory = new Factory();
FlyWeight flyWeight = factory.GetBike();
flyWeight.Ride("张三");
FlyWeight flyWeight2 = factory.GetBike();
flyWeight2.Ride("李四");
flyWeight2.Back("李四");
FlyWeight flyWeight3 = factory.GetBike();
flyWeight3.Ride("王五");
//FlyWeight flyWeight4 = factory.GetBike();
//flyWeight4.Ride("赵六");
//FlyWeight flyWeight5 = factory.GetBike();
//flyWeight5.Ride("田七");
Console.ReadKey();
}
}
/// <summary>
/// 共享单车的父类 小黄车 小蓝车
/// </summary>
abstract class FlyWeight
{
//外部状态 state----> 0 停止状态(归还了),可以随时被使用 1--骑行状态(使用了)
public int State { get; set; } //0 - 1 骑行或者归还的状态 外部状态
public int ID { get; set; } //二维码 内部状态
public abstract void Back(string user);//归还了
public abstract void Ride(string user);//骑走了
}
/// <summary>
/// 小黄车
/// </summary>
class LittlYellowBike : FlyWeight
{
public override void Back(string user)
{
Console.WriteLine("用户" + user + "归还了ID是" + this.ID + "的小黄车");
this.State = 0;
}
public override void Ride(string user)
{
Console.WriteLine("用户" + user + "骑走了ID是" + this.ID + "的小黄车");
this.State = 1;
}
}
class Factory
{
//维护所有的小黄车对象
List<FlyWeight> listBikes = new List<FlyWeight>();
/// <summary>
/// 创建小黄车的初始对象
/// </summary>
public Factory()
{
for (int i = 0; i < 3; i++)
{
listBikes.Add(new LittlYellowBike() { ID = i + 1 });
}
}
public FlyWeight GetBike()
{
for (int i = 0; i < listBikes.Count; i++)
{
//判断state的状态
if (listBikes[i].State == 0)
{
return listBikes[i];
}
}
//循环没执行,说明没有可用的自行车,创建一个新的
LittlYellowBike littlYellowBike = new LittlYellowBike() { ID = listBikes.Count+1};
listBikes.Add(littlYellowBike);
//拿最后一辆车
return listBikes[listBikes.Count - 1];
}
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 ## 14、中介者设计模式 ## 15、发布-订阅模式(观察者设计模式) - 常用于UP主发布视频是向粉丝推送或者UP主向粉丝推送信息 ```C# using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 解耦训练 { internal class Program { static void Main(string[] args) { //UP主 HappyNewYear happyNewYear = new HappyNewYear() { Information = "三里屯蹦迪" }; //粉丝 Student s1 = new Student() { Name = "张三"}; Student s2 = new Student() { Name = "李四" }; Student s3 = new Student() { Name = "王五" }; Student s4 = new Student() { Name = "赵六" }; //让粉丝开始关注主播 happyNewYear.Attach(s1); happyNewYear.Attach(s2); happyNewYear.Attach(s3); happyNewYear.Attach(s4); happyNewYear.Notify(); Console.ReadKey(); } } /// <summary> /// UP主的父类 /// </summary> public interface ISubject { void Attach(IObserver observer); void Notify(); } /// <summary> /// UP主 /// </summary> public class HappyNewYear : ISubject { /// <summary> /// 要通知给粉丝的消息 /// </summary> public string Information { get; set; } // 维护所有的粉丝 private List<IObserver> observers = new List<IObserver>(); /// <summary> /// 添加粉丝 /// </summary> /// <param name="observer"></param> public void Attach(IObserver observer) { observers.Add(observer); } /// <summary> /// 通知所有的粉丝,关于HappyNewYear的活动信息 /// </summary> public void Notify() { foreach (var observer in observers) { // 每一个粉丝,都能收到消息 observer.Update(Information); } } } /// <summary> /// 粉丝的父类 /// </summary> public interface IObserver { void Update(string message); } /// <summary> /// 粉丝 /// </summary> public class Student : IObserver { public string Name { get; set; } /// <summary> /// 粉丝收到Up主的消息 /// </summary> /// <param name="message">收到的消息</param> public void Update(string message) { // 收Up主的消息 Console.WriteLine("{0}收到了2024年12月31号去{1}消息", this.Name, message); } } }
16、迭代器设计模式
17、访问者设计模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace _08_访问者设计模式{ internal class Program { static void Main (string [] args ) { Visitors visitorsHR = new HR(); Visitors visitorsCW = new CaiWu(); FullTimeWorker fullTimeWorker1 = new FullTimeWorker("全职张三" ,180 ,5000 ); FullTimeWorker fullTimeWorker2 = new FullTimeWorker("全职李四" , 140 , 5000 ); FullTimeWorker fullTimeWorker3 = new FullTimeWorker("全职王五" , 120 , 5000 ); PartTimeWorker partTimeWorker1 = new PartTimeWorker("兼职赵六" , 200 , 5000 ); PartTimeWorker partTimeWorker2 = new PartTimeWorker("兼职赵六" , 200 , 5000 ); PartTimeWorker partTimeWorker3 = new PartTimeWorker("兼职赵六" , 200 , 5000 ); ObjectStucture os = new ObjectStucture(); os.AddElements(fullTimeWorker1); os.AddElements(fullTimeWorker2); os.AddElements(fullTimeWorker3); os.AddElements(partTimeWorker1); os.AddElements(partTimeWorker2); os.AddElements(partTimeWorker3); os.VisitElements(visitorsHR); Console.ReadKey(); } } abstract class Visitors { public abstract void Visit (FullTimeWorker fullTimeWorker ) ; public abstract void Visit (PartTimeWorker partTimeWorker ) ; } class HR : Visitors { public override void Visit (FullTimeWorker fullTimeWorker ) { double hours = fullTimeWorker.WorkHours; string name = fullTimeWorker.Name; if (hours > 160 ) { Console.WriteLine("人事部建议给{0}加薪" , name); } else { Console.WriteLine("人事部建议干掉{0}" ,name); } } public override void Visit (PartTimeWorker partTimeWorker ) { double hours = partTimeWorker.WorkHours; string name = partTimeWorker.Name; if (hours > 160 ) { Console.WriteLine("人事部建议给{0}友好的劝退" , name); } else { Console.WriteLine("赶紧让{0}滚犊子" ,name); } } } class CaiWu : Visitors { public override void Visit (FullTimeWorker fullTimeWorker ) { double hours = fullTimeWorker.WorkHours; double salary = fullTimeWorker.Salary; string name = fullTimeWorker.Name; if (hours >= 160 ) { Console.WriteLine("{0}本月应出勤160小时,实际出勤{1}小时,合计加班{2}小时,总薪资为{3}" , name, hours, hours - 160 , hours * 100 ); } else { Console.WriteLine("{0}本月应出勤160小时,实际出勤{1}小时,合计旷工{2}小时,总薪资为{3}" , name, hours, 160 - hours, hours * 80 ); } } public override void Visit (PartTimeWorker partTimeWorker ) { double hours = partTimeWorker.WorkHours; double salary = partTimeWorker.Salary; string name = partTimeWorker.Name; Console.WriteLine("{0}本月出勤{1}小时,合计薪资为{2}" , name, hours, hours * 20 ); } } abstract class Element { public string Name { get ; set ; } public int WorkHours { get ; set ; } public double Salary { get ; set ; } public Element (string name, int workHours, double salary ) { this .Name = name; this .WorkHours = workHours; this .Salary = salary; } public abstract void Accept (Visitors visitors ) ; } class FullTimeWorker : Element { public FullTimeWorker (string name, int hours, double salary ) : base (name, hours, salary ) { } public override void Accept (Visitors visitors ) { visitors.Visit(this ); } } class PartTimeWorker : Element { public PartTimeWorker (string name, int hours, double salary ) : base (name, hours, salary ) { } public override void Accept (Visitors visitors ) { visitors.Visit(this ); } } class ObjectStucture { private List<Element> list = new List<Element>(); public void AddElements (Element element ) { list.Add(element); } public void VisitElements (Visitors visitors ) { foreach (var item in list) { item.Accept(visitors); } } } }
18、责任链设计模式 19、模板设计模式 20、策略设计模式 21、命令设计模式 22、备忘录设计模式 23、状态设计模式 24、解释器设计模式