目录
1.C#编译环境、基础语法
F12查看函数被引用的地方,ctrl +减号 返回F10,debug时的一步步调试alt+s左键 选几行中的某些字段
calculator.repoort() 加括号表示调用方法 calculator.repoort 表示方法名
1.查看变量类型Debug.WriteLine(array3.GetType().ToString())2.抛出异常try {可能会出现异常的代码块;}//try和catch之间不能有其它的代码 catch {出现异常后要执行的代码块;}3.查看两变量或对象是否是一个值?Console.WriteLine{"{0}",stu.GetHashCode()};4.将文件中一个变量名统一修改成另外一个对一个修改完后,按 ctrl+点 实现 5.类是典型的引用类型6.Action action1 = new Action(stu1.dohomework); stu1.dohomework 是函数名7.1.类中定义方法时,后面不用加; 只有执行的语句要加;2.stu1.dohomework()是方法的调用 stu1.dohomework 是函数名 public double Price { get; set; } Action action1 = new Action(stu1.dohomework); stu1.dohomework 是函数名8.registerMonitor.get_Reg = get_reg_values; get_reg_values没有变量类型,没有括号表示方法,那么是委托9.使用alt+enter对写的代码进行补充10.//委托类型创建 为 order事件创建 public delegate void OrderEventHandler(Customer customer, OrderEventArgs e); private OrderEventHandler orderEventHandler;//委托字段,用来存储事件处理器11.一个类可以继承单个类,一个类可以有多个接口,一个接口也可以继承多个接口12. new 创建的是静态类型,typeof 拿到的是动态描述
c# 了解
1.net 运行平台上,运行vb,c#,c++语言(.net环境为vb,c#,c++封装了各种工具包) .net core跨平台开发(可运行win linux) 相当于java开发工具包jdk上,包含java运行环境(jre,jvm+java系统类库)和java工具
2.c#工具 visual studio 2019
关键字声明 class类 namespace int(申明整数变量)
//单行注释
多选注释
// 放到类、方法前按下///进行注释
变量为小数1.123,系统将其认为是double 型, float a=1.123报错 double a=1.123正确
string s='“” 与s=null 区别:“”“”的字符串为空, null直接就是空,存字符串的地方都没有,只有string才可以=null,其他类型变量不可以
int x=2;
show(++x) ; x=3 前++先执行
show(x); x=3
string a=5;
show(a++); a=5 后++ 后执行
show(a); a=6
IF要一个个判断才能选择某个分支,switch直接进入那个分支
private void InitializeComponent() { MessageBox.Show("linyang"); int a = 2; switch (a) //a可以为数字也可为string { case 1: MessageBox.Show("1"); break; case 2: MessageBox.Show("2"); break;//必须要break }
//for 循环直接循环 while 预设一个条件,当条件满足时进入循环, do {}while 先执行,达到条件退出 for (int a =2; a<4; a++) { MessageBox.Show(a.ToString()); };int i = 1;while (i <=3) { MessageBox.Show((i++).ToString());}int b = 1;do { MessageBox.Show((b).ToString()); b++;}while (b < 4);
每次new就会开辟一个新地址,尽管内容一次,但不是同一个
//关键字 int,int[] 声明变量类型,new 创建数组 int q = 2; int[] a = new int[6]; int[] b = new int[3] { 1,2,3}; int[] c = new int[] { 'a',2,3}; MessageBox.Show(c[0].ToString()); //输出97
} public void Sellhouse(string want) { want = "1111"; MessageBox.Show(want.ToString()); } public void Sellhouse1(out string want) { want = "1111"; //有out时必须要赋值,否则报错 MessageBox.Show(want.ToString()); } public void Sellhouse2(ref string want) { want = "1111"; //有ref时,谁调用它必须赋初值,否则报错 MessageBox.Show(want.ToString()); }
数组是连续的不能add,delete(new int[3])
集合(arraylist支持add,delete但是装箱拆箱耗时-由于存储变量类型不一致情况导致,
list泛型 list约束了只支持一种类型)
int[] a=new int[5]
Arraylist a=new Arraylist()
List<int> a = new List<int>( ); List<int> b = new List<int> { 1,2,2}; List<Person> p = new List<Person>(); a.Add(112); a[0] = 4; a.Insert(0, 3); a.RemoveAt(0); a.Remove(4); a.Clear(); p.Add(new Person() { }); Dictionary<int, string> c = new Dictionary<int, string>(); Dictionary<int, string> d = new Dictionary<int, string> { //对象初始化器 { 2,"333"},{4,"555"} }; c.Add(1, "111"); c.Add(2, "222"); c.Add(3, "333"); string value = c[2];//通过键索引到值; “222” bool f=c.Remove(1);//通过键删除那个值
int[] a = new int[] { 3,4,5}; foreach (int i in a) { MessageBox.Show(i.ToString()); } List<int> b = new List<int> { 2,3,4}; foreach(int i in b) { MessageBox.Show(i.ToString()); } Dictionary<string, string> c = new Dictionary<string, string>() { {"aa","aaaaa" },{"bb","bbbb" } }; foreach (KeyValuePair<string,string> i in c) { string key = i.Key; string value = i.Value; }
2.Winform-后续未学完
一、类成员
0常量
math.PI 就是常量 运算效率高,不用从内存中读
1字段
实例字段初始化时机:创建一个类时
静态字段初始化时机:这个程序被加载时,字段在声明时就初始化了,只初始化一次
2属性
1属性完整申明
// 在类中输入 propfull按两下tab自动生成 class person { private int age; public int Age { get { return age; } set { if (value >= 0 && value <= 120)//这个value是微软特定设置在set下的,不用申明 { age = value; } else { throw new Exception("age value has error11111"); } } } }//使用,使用private后 person p1 = new person(); p1.Age=100;
2属性简易申明,对字段没有保护措施
// 在类中输入 prop按两下tab自动生成 class person { public int MyProperty { get; set; } }
3字段int age->方法对 get() ->属性Age{get;set}的推演
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConsoleApp1{ class Program { static void Main(string[] args) { try { Student stu1 = new Student(); stu1.Age = 20;//使用private后,类调用属性只能get set方法 //stu1.Setage(20); Student stu2 = new Student(); //stu2.Setage(20); stu2.Age = 20; Student stu3 = new Student(); //stu3.Setage(810); stu3.Age = 210; int avgage = (stu1.Age + stu2.Age + stu3.Age) / 3; Console.WriteLine(avgage); Console.Read(); } catch(Exception ee) { Console.WriteLine(ee.Message);//"age value has error"打印到前台 Console.Read(); } } } class Student { private int age; public int Getage () { return this.age; } public void Setage(int value)//属性可以对变量防护 { if (value >= 0 && value <= 120) { this.age = value; } else { throw new Exception("age value has error"); } } private int age; public int Age { get { return this.age; } set { if (value >= 0 && value <= 120)//这个value是微软特定设置在set下的,不用申明 { this.age = value; } else { throw new Exception("age value has error11111"); } } } }}
3索引器
索引器用在集合中
//输入index 按两下TAB生成using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConsoleApp1{ class Program { static void Main(string[] args) { try { Student stu = new Student(); var mathscore = stu["Math"]; Console.WriteLine(mathscore==null); Console.Read(); } catch(Exception ee) { Console.WriteLine(ee.Message);//"age value has error"打印到前台 Console.Read(); } } } class Student { private Dictionary<string, int> score = new Dictionary<string, int>(); public int? this[string subject] //int?可空int型号 subject自己定义的成绩科目名为subject { get { if (this.score.ContainsKey(subject)) { return this.score[subject]; } else { return null; } } set { if (value.HasValue == false) { throw new Exception("score cannot be null"); } if (this.score.ContainsKey(subject)) { this.score[subject]=value.Value;//int?可空int型号 } else { this.score.Add(subject, value.Value); } } } } }
5方法
5.1值参数(创建副本,方法内对值的操作,不会影响原来变量的值)
引用类型,不创建新对象
5.2引用参数(传的是地址,方法内对值的操作,出了方法后原来的值也被修改)
引用参数在传入方法前必须有个明确的赋值,然后在方法中修改
5.3 输出参数(普通方法一次调用只产出一个返回值,但希望一次调用返回多个输出值,所以用输出参数)
讲解的时值先讲值 引用变化,再讲类引用变化
5.4 数组参数 parmas(可供函数输出多个值)
5.5 具名参数(调用方法时,参数带有名字,位置随意)
5.6 可选参数(方法定义声明时,有默认值)
5.7 扩展方法(this参数)
二、委托
1委托(c# Action,Func常规委托)
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConsoleApp1{ class Program { static void Main(string[] args) { Calculator calculator = new Calculator(); Action action = new Action(calculator.Report);//Action: 方法是void,并且无参数 action.Invoke();//委托调用 action();//模仿c中函数指针的书写格式 calculator.Report();//直接调用方法名 //<第一个int为返回值, 第二三个int为函数输入> Func<int, int, int> func1 = new Func<int, int, int>(calculator.Add);//Func :方法是有返回,有参数 Func<int, int, int> func2 = new Func<int, int, int>(calculator.Sub); int x = 100; int y = 200; int z = 0; z = func1.Invoke(x, y);//委托调用 Console.WriteLine(z); z = func2.Invoke(x, y); Console.WriteLine(z); func1(x, y);//模仿c中函数指针的书写格式 } } class Calculator { public void Report() { Console.WriteLine("i have 3 methods"); } public int Add(int a,int b) { int result = a + b; return result; } public int Sub(int a, int b) { int result = a - b; return result; } } }
2委托声明 (delegate自定义委托)
3委托使用(把方法当做参数会给另一个方法:模板法,回调法)
实现目的:方法中调用方法
现实中是无法操作的,所以采用模板方法+用委托类型参数封装的方法的方式来实现,委托相当于一个指针,可以指定任意方法,就可以实现方法调方法。
模板方法:方法中 输入 用委托类型参数封装的方法
回调方法:方法中 在调用 用委托类型参数封装的方法 时,有条件判断
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConsoleApp1{ class Program { static void Main(string[] args) { ProdectFactory prodectFactory = new ProdectFactory(); WrapFactory wrapFactory = new WrapFactory(); //<第一个int为返回值, 第二三个int为函数输入> // Func func1 = new Func(calculator.Add);//Func :方法是有返回,有参数 //1委托封装方法 //Product为委托的返回类型 ,func1为委托名 =new委托的返回值类型是Product,委托的函数名称=prodectFactory.MakePiza Func<Product> func1 = new Func<Product>(prodectFactory.MakePiza); Func<Product> func2 = new Func<Product>(prodectFactory.Makecar); Logger logger = new Logger(); Action<Product> log = new Action<Product>(logger.Log); //2调用模板方法,返回值为box1 Box box1=wrapFactory.WrapProduct(func1,log); Box box2 = wrapFactory.WrapProduct(func2,log); Console.WriteLine(box1.product.Name); Console.WriteLine(box2.product.Name); Console.Read(); } class Logger { public void Log(Product product) { Console.WriteLine("Product '{0}' created at {1},price is {2}", product.Name, DateTime.UtcNow, product.Price); } } class Product { public string Name { get; set; } //类属性是string public double Price { get; set; } } class Box { public Product product { get; set; }//类属性是一个类 } class WrapFactory { //WrapProduct 委托的模板方法,Box方法的返回值 //委托模板方法的输入是委托函数 Func getProduct public Box WrapProduct(Func<Product> getProduct, Action<Product> logCallback) { Box box = new Box(); Product product = getProduct.Invoke(); if (product.Price > 50) { logCallback(product); } box.product=product; return box; } } class ProdectFactory { public Product MakePiza() { Product product = new Product(); product.Name = "Pizza"; product.Price = 12; return product; } public Product Makecar() { Product product = new Product(); product.Name = "car"; product.Price = 100; return product; } } } }
4委托高级使用(多播委托\异步委托调用)
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;namespace ConsoleApp1{ class Program { static void Main(string[] args) { Student stu1 = new Student() { id = 1, pencolor = ConsoleColor.Yellow }; Student stu2 = new Student() { id = 2, pencolor = ConsoleColor.Green }; Student stu3 = new Student() { id = 3, pencolor = ConsoleColor.Red }; //------------------------------------------------------------ // 4显式异步调用 Task task1 = new Task(new Action(stu1.dohomework)); Task task2 = new Task(new Action(stu2.dohomework)); Task task3 = new Task(new Action(stu3.dohomework)); task1.Start(); task1.Start(); task1.Start(); for (int i=0; i < 5; i++) { Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("main thread{0}", i); Thread.Sleep(1000); Console.Read(); } } class Student { public int id { get; set; } public ConsoleColor pencolor { get; set; } public void dohomework() { for (int i =0; i <5;i++) { Console.ForegroundColor = this.pencolor; Console.WriteLine("student{0} doing homework {1} hours", this.id, i); Thread.Sleep(1000); } } } }}
三、事件
1事件定义
一个对象有事件,对象通过事件的发生来通知其他对象
程序员自己写的代码 订阅一个按钮,当按钮点击事件由客户触发时,那么代码就会对其进行响应。
用户操作下鼠标,就会执行一块程序,鼠标不用,那么这块程序就不执行。称这块程序为事件驱动程序。
2事件应用(5要素)
事件的拥有者决定事件是否发生
按钮的内部逻辑(按下松开),触发了自己的click事件,
click事件发生了就会告知相应的订阅者,
相应的订阅者就会产生相应的行为。
这个约定就是委托,事件建立在委托上
事件与响应方法是可以1对多,多对1
订阅的挂接方式this.button.click+=this.buttoonclicked;this.button.click+=new EventHandler(this.buttoonclicked);this.button.click+=(object sender, EventArgs e)=>{ this.textBox.text='hah';}; //流行this.button.click+=delegate(object sender, EventArgs e){ this.textBox.text='hah';}//匿名方法过时
事件与响应方法是可以1对多,多对1
//一星展示using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Timers;namespace ConsoleApp1{ class Program { static void Main(string[] args) { Timer timer = new Timer(); // timer.Elapsed事件的拥有者Timer timer.Interval = 1000; Boy boy = new Boy(); //事件的订阅者 Girl girl = new Girl(); // 订阅者的处理器 +=表示订阅 拿方法订阅一个事件时,它们要遵守约定:约定就是委托类型 // timer.Elapsed的类型就是 public delegate void ElapsedEventHandler(object sender, ElapsedEventArgs e); // 所以使用alt+enter自动按照委托形式对boy.Action进行方法创建 timer.Elapsed += boy.Action; //timer.Elapsed 为事件,boy.Action为事件处理器 timer.Elapsed += girl.Action; //一个事件两个订阅者 timer.Start(); Console.ReadLine(); } class Boy { internal void Action(object sender, ElapsedEventArgs e) { Console.WriteLine("Jump"); } } class Girl { internal void Action(object sender, ElapsedEventArgs e) { Console.WriteLine("sing"); } } } }
//三星展示using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Timers;using System.Windows.Forms;namespace ConsoleApp1{ class Program { static void Main(string[] args) { Form form=new Form();//事件的拥有者 Controller controller = new Controller(form);//事件的响应者 form.ShowDialog(); } class Controller { private Form form; public Controller(Form form) { if (form != null) { this.form = form; this.form.Click += this.Formclicked;//约定 } } private void Formclicked(object sender, EventArgs e) { this.form.Text = DateTime.Now.ToString(); } } }}
//自己调自己,两星事件using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Timers;using System.Windows.Forms;namespace ConsoleApp1{ class Program { static void Main(string[] args) { Myform myform = new Myform(); myform.Click += myform.Formclicked; myform.ShowDialog(); } class Myform : Form { internal void Formclicked(object sender, EventArgs e) { this.Text = DateTime.Now.ToString(); } } }}
//三星:事件的拥有者是响应者的成员using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Timers;using System.Windows.Forms;namespace ConsoleApp1{ class Program { static void Main(string[] args) { Myform myform = new Myform(); myform.ShowDialog(); } } class Myform : Form { private TextBox textBox; private Button button;//form的字段成员,拥有者 public Myform() { this.textBox = new TextBox(); this.button = new Button(); this.Controls.Add(this.button); this.Controls.Add(this.textBox); this.button.Click += this.buttonCllicked; //form =响应者 this.button.Text = "sss"; } private void buttonCllicked(object sender, EventArgs e) { this.textBox.Text = "hello world```````````````````````````"; } }}
3事件自定义
委托是事件的底层基础,事件是委托的上层建筑
//第三种using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;using System.Timers;using System.Windows.Forms;namespace ConsoleApp1{ class Program { static void Main(string[] args) { Customer customer = new Customer(); //1事件拥有者 Waiter waiter = new Waiter();//2事件的响应者 customer.Order += waiter.Action;//事件 , 事件处理器 事件拥有者的内部逻辑触发了事件 customer.Action();//事件触发 customer.Paybill(); } } //事件的信息 public class OrderEventArgs:EventArgs { public string Dishname { get; set; } public string Size { get; set; } } //委托类型创建 为 order事件创建 public delegate void OrderEventHandler(Customer customer, OrderEventArgs e); public class Customer //1事件拥有者 { private OrderEventHandler orderEventHandler;//委托字段,用来存储事件处理器 public event OrderEventHandler Order //2事件 { add { this.orderEventHandler += value; } remove { this.orderEventHandler -= value; } } public double Bill { get; set; } public void Paybill () { Console.WriteLine("i will pay ¥{0}", this.Bill); } public void Walk() { Console.WriteLine("walk into restaurant"); } public void Sitdown() { Console.WriteLine("Sitdown"); } public void Think()//事件触发 { for (int i=0; i < 5; i++) { Console.WriteLine("let me thikn''''"); Thread.Sleep(1000); } if (this.orderEventHandler != null)//如果没人订阅这个事件,事件发生时会报错 { OrderEventArgs e = new OrderEventArgs(); e.Dishname = "KONGBAO JIDING"; e.Size = "large"; this.orderEventHandler.Invoke(this, e); } } public void Action() { Console.ReadLine(); this.Walk(); this.Sitdown(); this.Think(); } } public class Waiter { public void Action(Customer customer, OrderEventArgs e) { Console.WriteLine("i will serve you dish {0}", e.Dishname); double price = 10; switch (e.Size) { case "small": price = price * 0.5; break; case "large": price = price * 2; break; default: break; } customer.Bill += price; } }}
四、类
1构造器、析构器
2.类修饰符(public\internal\abstract)
类的继承
sealed修饰类后,这个类不能被当成基类使用
一个类只能有一个基类
子类的类访问级别不能超越基类
横向扩展对类成员的扩充,纵向扩展对类成员的重写
子类是对父类的全盘继承
类成员的访问级别 低于类的访问级别
类定义默认是public ;类是属性默认为private
public 一个solution的多个项目都可访问
internal 在一个项目中的多个类中访问
private 只在当前类中使用,就算继承也不能访问
protected 修饰的类成员,此类成员只能被继承的类所调用
3类的继承
五、接口、抽象类
(人–接口–手机)多个人可分别使用不同款式手机
面向对象设计基本原则,通过设计的规则,让代码更为规范
abstract抽象类:函数成员未被完全实现的类(无方法体),不能实例化,抽象类只能作为基类,为子类服务,子类进行重写
abstract抽象类 一方面是用于子类继承,第二方法抽象类父类变量引用子类实例,代查
concrete具体类
开闭原则:在设计类的时候,把那些固定不变的方法,属性进行封装,把来回变动的采用抽象类,抽象方法供子类使用
接口,抽象类,具体类
//耦合过多,car依赖于engine,engine出了问题 car也出问题,所以使用接口来解耦合using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConsoleApp2{ class Program { static void Main(string[] args) { var engine = new Engine(); var car = new Car(engine); car.Run(3); Console.WriteLine(car.Speed); Console.ReadKey(); } } class Engine { public int RPM { get; private set; } public void Work(int gas) { this.RPM = 1000 * gas; } } class Car { private Engine _engine; public Car(Engine engine) { _engine = engine; } public int Speed { get; private set; } public void Run(int gas) { _engine.Work(gas); this.Speed = _engine.RPM / 100; } }}
//用接口来解耦合using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConsoleApp2{ class Program { static void Main(string[] args) { var user = new phoneuser(new nokia()); var user1 = new phoneuser(new erision()); user.usephone(); Console.Read(); } } class phoneuser { private iphone _phone; public phoneuser( iphone phone) { _phone = phone; } public void usephone() { _phone.dail(); _phone.pickup(); _phone.send(); _phone.receive(); } } interface iphone { void dail(); void pickup(); void send(); void receive(); } class nokia : iphone { public void dail() { Console.WriteLine("dailing........"); } public void pickup() { Console.WriteLine("pickup......"); } public void receive() { Console.WriteLine("receiving......."); } public void send() { Console.WriteLine("sending......"); } } class erision : iphone { public void dail() { Console.WriteLine("dailing-------"); } public void pickup() { Console.WriteLine("pickup---------"); } public void receive() { Console.WriteLine("receiving-------"); } public void send() { Console.WriteLine("sending--------"); } }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConsoleApp2{ class Program { static void Main(string[] args) { var fan = new deskfan(new powersupply()); Console.WriteLine(fan.work()); Console.Read(); } interface ipowersupply { int getpower();//定义一个返回值为int 的方法,无方法体 } class powersupply:ipowersupply { public int getpower() { return 100; } } class deskfan { private ipowersupply _powersupply;//由耦合函数powersupply换成接口函数 ipowersupply public deskfan(ipowersupply powersupply)//由耦合函数powersupply换成接口函数 ipowersupply { _powersupply = powersupply; } public string work() { int power = _powersupply.getpower(); if (power < 0) { return "wont work"; } else if (power < 100) { return "slow"; } else if (power < 200) { return "work fine"; } else { return "warning"; } } } } }
六、反射、依赖注入
## 一个类多个可以多个接口,接口也可继承多个接口interface Itrank: IVehicle, Iweapon class Program { static void Main(string[] args) { var driver = new Driver(new Car()); var driver1 = new Driver(new Truck()); var driver2 = new Driver(new lighttrank()); driver.Drive(); driver1.Drive(); driver2.Drive(); Console.ReadKey(); } class Driver { private IVehicle _vehicle; public Driver(IVehicle vehicle) { _vehicle = vehicle; } public void Drive() { _vehicle.Run(); } } interface IVehicle { void Run(); } class Car : IVehicle { public void Run() { Console.WriteLine("car is running"); } } class Truck : IVehicle { public void Run() { Console.WriteLine("Truck is running"); } } interface Iweapon { void Fire(); } interface Itrank: IVehicle, Iweapon { void Run(); void Fire(); }
## int[],ArrayList都继承了ICollection类,所以都可用于foreach的迭代namespace ConsoleApp2{ class Program { static void Main(string[] args) { int[] num1 = { 1, 2, 3, 4, 5 }; ArrayList num2 = new ArrayList { 1, 2, 3, 4, 5 }; Console.WriteLine(Sum(num1)); Console.WriteLine(Sum(num2)); Console.ReadKey(); } static int Sum(ICollection nums) { int sum = 0; foreach(var n in nums) { sum += (int)n; } return sum; } }}
//接口的显示实现,c#独有//void Ikill.Kill()//显示实现所有成员时, wk.Kill()是调不到此方法的//Ikill ikill = wk; ikill.Kill(); 只有Ikill变量时,才能调用Kill()方法namespace ConsoleApp2{ class Program { static void Main(string[] args) { var wk = new Warmkill(); wk.Kill(); Ikill ikill = wk; ikill.Kill(); Console.ReadKey(); } interface Igentleman { void Love(); } interface Ikill { void Kill(); } class Warmkill : Igentleman, Ikill { public void Love() { Console.WriteLine("love you"); } void Ikill.Kill()//显示实现所有成员 { throw new NotImplementedException(); } } }}
开发在编译代码的时候相当于静态代码,软件给用户使用时,处于dynamic状态,需要交互。开发可以枚举1000种方法来处理用户可能的操作,但太臃肿,也有可能覆盖不到,所以需要自己程序可以以不变应万变的能力,这个能力就是反射
反射可以不用new的情况,创建与类一个的类型,而且可访问其内部方法,相当于解耦合(用new创建时,后面要接类型,一有类型就有依赖)
普通反射
反射的用途1-依赖注入:用注册的动态类型,创建的实例,注入到Driver构造器中
反射的用途2-利用反射追求更松的耦合
七、泛型(这里代码多练习)
1.类型膨胀,1000种产品就会有1000种box,不好维护
using System;using System.Collections;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConsoleApp2{ class Program { static void Main(string[] args) { Apple apple = new Apple() { Color="red"}; AppleBox applebox = new AppleBox() { cargo = apple }; Console.WriteLine(applebox.cargo.Color); Book book = new Book() { Name = "shuji" }; BookBox bookbox = new BookBox() { cargo = book }; Console.WriteLine(bookbox.cargo.Name); Console.ReadKey(); } class Apple { public string Color { get; set; }//Color属性 } class AppleBox { public Apple cargo { get; set; } }//cargo属性 class Book { public string Name { get; set; } } class BookBox { public Book cargo { get; set; } }//cargo属性 }}
2.成员膨胀:一个box类有多个属性,给不同的商品
3.通过向box中传objecet对象,可以快速装箱,但读取箱中内容时,不好操作
namespace ConsoleApp2{ class Program { static void Main(string[] args) { Apple apple = new Apple() { Color="red"}; Book book = new Book() { Name = "shuji" }; Box box1 = new Box() { cargo = apple }; Box box2 = new Box() { cargo = book }; Console.WriteLine(box1.cargo.Color);//此处已经将book对象转换成object对象,无法再获得book对象中属性 Console.WriteLine((box1.cargo as Apple)?.Color);//可类型转换 Console.ReadKey(); } class Apple { public string Color { get; set; }//Color属性 } class Book { public string Name { get; set; } } //成员膨胀,一个box中有多个属性,每次只使用其中的一个,当新商品来时,还得修改此类 class Box { public Object cargo { get; set; } }}}
4.使用泛型不会产生类型膨胀、成员膨胀
using System;using System.Collections;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConsoleApp2{ class Program { static void Main(string[] args) { Apple apple = new Apple() { Color="red"}; Book book = new Book() { Name = "shuji" }; //用泛型将box特化 Box<Apple> box1 = new Box<Apple>() { cargo = apple }; Box<Book> box2 = new Box<Book>() { cargo = book }; Console.WriteLine(box1.cargo.Color); Console.WriteLine(box2.cargo.Name); Console.ReadKey(); } class Apple { public string Color { get; set; }//Color属性 } class Book { public string Name { get; set; } } class Box<Tcargo> { public Tcargo cargo{ get; set; } }}}
5.泛型接口
泛型方法
成员膨胀
泛型方法(类型参数 加到zip方法后)
泛型委托
结构体类型是值类型,值类型:与值类型相关连的内存中存在的是此实例
值类型的copy: copy的是一个完整对象
变量类型的copy:是对同一个对象的引用(一份数据)
堆内存中的实例
结构体不能由其他结构体类型、类类型派生而来,只能由interface来
八、核心代码汇总
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Reflection;using System.Text;using System.Threading;using System.Threading.Tasks;using System.Timers;using System.Windows.Forms;namespace Core_knowledge{ public partial class Form1 : Form { //1类 //1.1属性方法定义 int a01 = 3; public double Price { get; set; } private void dosomething(string name) { Console.WriteLine($"[****Dosomething {name} start: 线程号:({Thread.CurrentThread.ManagedThreadId.ToString("00")})---{System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")}*******]"); long result = 0; for (int i = 0; i < 10000000; i++) { result += i; } Thread.Sleep(2000); Console.WriteLine($"[****Dosomething {name} end: 线程号:({Thread.CurrentThread.ManagedThreadId.ToString("00")})---{System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")}{result}*******]"); } //1.2默认构造器 Student()是将数值型变成0,其他类型设置为null Student stu = new Student(); //1.3构造器看着像方法,名子和类一样,有构造器后,引用创建对象时要传参否则报错-见class Student Student stu2 = new Student(5, "timo"); //1.4初始化器{id=1,name="timothy" } Student stu1 = new Student() { id = 1, name = "timothy" }; //1.5 析构器 ~Student() 函数在执行完后,说明这个对象没人用了就要释放,这里就会调用析构器,这里面可以写内存释放的代码 //1.6反射 //1.7横向扩展对类成员的扩充,纵向扩展对类成员的重写 //1.8父类类型变量引用 子类类型实例 子类 is a 父类 汽车是车 public void s() { Vehicle v = new Car();//到底是哪个run,与实例化有关,谁被new,谁的被执行,这里是car running v.run(); } //1.9枚举-在定义一个person职位时,有人知道person有多少个level,有人不知道,所以放到enum中统一管理 public void meiju() { Console.WriteLine((int)Level.employee); } //1.10.见struct Student1 : ISpeak -结构体类型是值类型,值类型:与值类型相关连的内存中存在的是此实例 //2 IF_FOR_SWITCH public void IF_FOR_SWITCH_foreach() { for (int c = 0; c < 5; c++) { int k = c; Task.Run( () => { Thread.Sleep(100); Console.WriteLine($"k={k}, i={c}"); } ); } int i = 0; if (i > 10) { Console.WriteLine(1); } else if (i > 0 && i < 10) { Console.WriteLine(2); } else { Console.WriteLine(3); } switch (i) { case 1: Console.WriteLine(1); break; case 2: Console.WriteLine(1); break; default: Console.WriteLine(1); break; } int[] p = new int[] { 1, 2, 3 }; foreach (int p1 in p) { } } //3常用代码 public void Commoncode() { //数据类型 int q = 2; int[] a = new int[6]; int[] b = new int[3] { 1, 2, 3 }; Console.WriteLine(a[1].ToString()); int[] c = new int[] { 'a', 2, 3 }; List<string> a1 = new List<string>() { "a", "b" }; Console.WriteLine(a1[1].ToString()); //List p = new List(); //p.Add(new Person() { }); a1.Add("112"); a[0] = 4; a1.Insert(0, "3"); a1.RemoveAt(0); a1.Remove("a"); a1.Clear(); Dictionary<int, string> d = new Dictionary<int, string> { //对象初始化器 { 2,"333"},{4,"555"} }; MessageBox.Show(c[0].ToString()); MessageBox.Show("1"); Console.WriteLine($"[------------主线程start: 线程号:({Thread.CurrentThread.ManagedThreadId.ToString("00")})---{System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")}-----]"); } //4Trycatch() public void Trycatch() { try { if (2 > 1) { throw new Exception(string.Format($"执行失败")); } } catch (Exception ex) { Console.WriteLine(ex.Message); } try { float a = 3; double b = 3.2; } catch (AggregateException aex) { foreach (var item in aex.InnerExceptions) { Console.WriteLine(item.Message); } } catch (Exception ex) { Console.WriteLine(ex.Message); } } //5委托使用-委托相当于一个指针,可以指定任意方法,就可以实现方法调方法。 public void action() { //5.1.无返回值委托-Action委托 Calculator calculator = new Calculator(); Action action = new Action(calculator.Report);//Action: 方法是void,并且无参数 action.Invoke();//委托调用 Action<string> action = this.dosomething;//委托带参数 Action action1 = () => this.dosomething("CC");//委托不带参数 Logger logger = new Logger(); Action<Product> log = new Action<Product>(logger.Log); //5.2.有返回值委托-Func委托 //<第一个int为返回值, 第二三个int为函数输入> Func<int, int, int> func1 = new Func<int, int, int>(calculator.Add);//Func :方法是有返回,有参数 int x = 100; int y = 200; int z = 0; int c = 0; z = func1.Invoke(x, y);//委托调用 func1(x, y);//模仿c中函数指针的书写格式 //Product为委托的返回类型 ,func1为委托名 委托的返回值类型是Product,委托的函数名称=prodectFactory.MakePiza //Func func1 = new Func(prodectFactory.MakePiza); //5.3.委托简单使用-delegate自定义委托 //public delegate int Calc(int x, int y);//自定义委托是个类,格式要与委托函数一致 Calc calc1 = new Calc(calculator.Add);//委托实例化 c = calc1.Invoke(x, y); //5.4.实现目的:方法中调用方法 //模板方法:方法中 输入 用委托类型参数封装的方法-具体看WrapProduct方法 //回调方法:方法中 在调用 用委托类型参数封装的方法 时,有条件判断-具体看WrapProduct方法 WrapFactory wrapFactory = new WrapFactory(); ProdectFactory prodectFactory = new ProdectFactory(); Action<Product> log1 = new Action<Product>(logger.Log); Func<Product> func2 = new Func<Product>(prodectFactory.MakePiza); //用委托将方法进行封装,然后将这个委托传到B方法中,在B方法中对委托进行调用,实现了方法中调用方的目的 //同时委托相当于一个指针,可以封装各式各样的方法,那么B方法也就可以调用任意方法 Box box1 = wrapFactory.WrapProduct(func2, log1); //5.5.多播委托\异步委托调用 //直接同步调用:使用方法名 Student stu1 = new Student() { id = 1, pencolor = ConsoleColor.Yellow }; Student stu2 = new Student() { id = 1, pencolor = ConsoleColor.Yellow }; Student stu3 = new Student() { id = 1, pencolor = ConsoleColor.Yellow }; stu1.dohomework(); //5.6.间接同步调用:使用单播、多播委托invoke Action action1 = new Action(stu1.dohomework); Action action2 = new Action(stu2.dohomework); Action action3 = new Action(stu3.dohomework); action1.Invoke();//单播委托 action1 += action2;//多播委托 action1 += action3; action1.Invoke(); //5.7.隐式异步调用:使用委托的begininvoke Action action4 = new Action(stu1.dohomework); action4.BeginInvoke(null, null);//第一个null为执行完线程后的回调函数 //5.8. 显示异步调用:使用thread或task Thread thread1 = new Thread(new ThreadStart(stu1.dohomework)); thread1.Start(); } //6.事件 public void shijian() { System.Timers.Timer timer = new System.Timers.Timer(); // timer.Elapsed事件的拥有者Timer timer.Interval = 3000; Boy boy = new Boy(); //事件的订阅者 Girl girl = new Girl(); // 订阅者的处理器 +=表示订阅 拿方法订阅一个事件时,它们要遵守约定:约定就是委托类型 // timer.Elapsed的类型就是 public delegate void ElapsedEventHandler(object sender, ElapsedEventArgs e); // 所以使用alt+enter自动按照委托形式对boy.Action进行方法创建 timer.Elapsed += boy.Action; //timer.Elapsed 为事件,boy.Action为事件处理器 timer.Elapsed += girl.Action; //一个事件两个订阅者 timer.Start(); Console.ReadLine(); //三星:事件的拥有者是响应者的成员,见class Myform : Form //事件自定义-可再找之间代码学习,学习过 } //7.抽象类 //abstract抽象类-不能实例化:函数成员未被完全实现的类(无方法体),抽象类只能作为基类,为子类服务,子类进行重写 见-abstract class vehicle1 //abstract抽象类 一方面是用于子类继承,第二方法抽象类父类变量引用子类实例,代查 //concrete具体类 //8.接口-纯虚类-不能实例化 见class phoneuser、interface vehiclebase public void jiekou() //(人–接口–(苹果手机,华为手机))多个人可分别使用不同款式手机 { var user = new phoneuser(new nokia()); var user1 = new phoneuser(new erision()); user.usephone(); Console.Read(); //一个类多个可以多个接口,接口也可继承多个接口interface Itrank: IVehicle, Iweapon var driver = new Driver(new Car1()); var driver1 = new Driver(new Truck()); driver.Drive(); driver1.Drive(); } //9.反射的用途 //9.1.反射的用途-依赖注入: 用注册的动态类型,创建的实例,注入到Driver构造器中 //开发在编译代码的时候相当于静态代码,软件给用户使用时,处于dynamic状态,需要交互。开发可以枚举1000种方法来处理用户可能的操作,但太臃肿,也有可能覆盖不到,所以需要自己程序可以以不变应万变的能力,这个能力就是反射 //反射可以不用new的情况,创建与类一个的类型,而且可访问其内部方法,相当于解耦合(用new创建时,后面要接类型,一有类型就有依赖) //10泛型 List<int> list = new List<int>();//参考泛型写法:前面List类型中只能存放int类的变量 public void fanxing() { Apple apple = new Apple() { Color = "red" }; Book book = new Book() { Name = "shuji" }; //用泛型将box特化 Box<Apple> box1 = new Box<Apple> { cargo = apple }; Box<Book> box2 = new Box<Book>() { cargo = book }; Console.WriteLine(box1.cargo.Color); Console.WriteLine(box2.cargo.Name); //泛型接口 Student<int> stu = new Student<int>(); stu.ID = 101; stu.Name = "asd"; } //11.partial类 相当于一个类被切分成多个部分进行存放-要保持命名空间一致(namespace) public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { //Trycatch(); //Commoncode(); //shijian(); //Myform myform = new Myform(); //myform.ShowDialog(); fanxing(); } } class Calculator { public void Report() { Console.WriteLine("i have 3 methods"); } public int Add(int a, int b) { int result = a + b; return result; } public int Sub(int a, int b) { int result = a - b; return result; } } public delegate int Calc(int x, int y);//自定义委托是个类,格式要与委托函数一致 class Logger { public void Log(Product product) { Console.WriteLine("Product '{0}' created at {1},price is {2}", product.Name, DateTime.UtcNow, product.Price); } } class Product { public string Name { get; set; } //类属性是string public double Price { get; set; } } class Box { public Product product { get; set; }//类属性是一个类 } class WrapFactory { //WrapProduct 委托的模板方法,Box方法的返回值 //委托模板方法的输入是委托函数 Func getProduct public Box WrapProduct(Func<Product> getProduct, Action<Product> logCallback) { Box box = new Box(); Product product = getProduct.Invoke(); if (product.Price > 50) { logCallback(product); } box.product = product; return box; } } class ProdectFactory { public Product MakePiza() { Product product = new Product(); product.Name = "Pizza"; product.Price = 12; return product; } public Product Makecar() { Product product = new Product(); product.Name = "car"; product.Price = 100; return product; } } class Student { public Student()//创建一个空的,给不传参使用,否则会报错 { } public Student(int Id, string Name)//构造器看着像方法,名子和类一样,有构造器后,引用创建对象时要传参否则报错 { this.id = Id; this.name = Name; } public static int Amount { get; set; } static Student() { Amount = 100; } ~Student() { Console.WriteLine("bye bye"); } public int id { get; set; } public string name { get; set; } public ConsoleColor pencolor { get; set; } public void dohomework() { for (int i = 0; i < 5; i++) { Console.ForegroundColor = this.pencolor; Console.WriteLine("student{0} doing homework {1} hours", this.id, i); Thread.Sleep(1000); } } } class Boy { internal void Action(object sender, ElapsedEventArgs e) { Console.WriteLine("Jump"); } } class Girl { internal void Action(object sender, ElapsedEventArgs e) { Console.WriteLine("sing"); } } //三星:事件的拥有者是响应者的成员 class Myform : Form { private TextBox textBox; private Button button;//form的字段成员,拥有者 public Myform() { this.button = new Button(); this.button.Location = new System.Drawing.Point(276, 176); this.button.Size = new System.Drawing.Size(75, 23); this.button.Text = "sss"; this.textBox = new TextBox(); this.textBox.Location = new System.Drawing.Point(176, 176); this.textBox.Size = new System.Drawing.Size(120, 23); this.Controls.Add(this.button); this.Controls.Add(this.textBox); this.button.Click += this.buttonCllicked; //form =响应者 } private void buttonCllicked(object sender, EventArgs e) { this.textBox.Text = "hello world```````````````````````````"; } } class Vehicle { public Vehicle() { this.Owner = "NA"; } public Vehicle(string owner) { this.Owner = owner; } public virtual void run() { Console.WriteLine("vehicle is running"); } public string Owner { get; set; } } class Car : Vehicle { public Car() { this.Owner = "car"; } //public Car() :base("NA")//基类构造器中有参数,子类构造器也要声明 //{ // this.Owner ="car owner"; //} public void doing() { Console.WriteLine("222"); } public override void run() { Console.WriteLine("car is running"); } } abstract class vehicle1 { public void fill()// { Console.WriteLine("111"); } public abstract void run1();//抽象方法 } class car1 : vehicle1 { public override void run1() { Console.WriteLine("111"); } } interface vehiclebase { void stop(); void fill(); } class phoneuser { private iphone _phone; public phoneuser(iphone phone) { _phone = phone; } public void usephone() { _phone.dail(); _phone.pickup(); _phone.send(); _phone.receive(); } } interface iphone { void dail(); void pickup(); void send(); void receive(); } class nokia : iphone { public void dail() { Console.WriteLine("dailing........"); } public void pickup() { Console.WriteLine("pickup......"); } public void receive() { Console.WriteLine("receiving......."); } public void send() { Console.WriteLine("sending......"); } } class erision : iphone { public void dail() { Console.WriteLine("dailing-------"); } public void pickup() { Console.WriteLine("pickup---------"); } public void receive() { Console.WriteLine("receiving-------"); } public void send() { Console.WriteLine("sending--------"); } } class Driver { private IVehicle _vehicle; public Driver(IVehicle vehicle) { _vehicle = vehicle; } public void Drive() { _vehicle.Run(); } } interface IVehicle { void Run(); } class Car1 : IVehicle { public void Run() { Console.WriteLine("car is running"); } } class Truck : IVehicle { public void Run() { Console.WriteLine("Truck is running"); } } interface Iweapon { void Fire(); } interface Itrank : IVehicle, Iweapon { void Run(); void Fire(); } class Tank{ void run() { } void fire() { } } class Book { public string Name { get; set; } } class Apple { public string Color { get; set; } } class Box<Tcargo> { public Tcargo cargo { get; set; } } interface IUnique<TId> { TId ID { get; set; } } class Student<TId>: IUnique<TId> { public TId ID { get; set; } public string Name { get; set; } } enum Level { employee=100, manager, boss=300, } interface ISpeak { void speak(); } struct Student1 : ISpeak { public Student1(int id )//结构体不能使用显示无参函数,这里面必须有值 { this.ID = id; } public int ID { get; set; } public void speak() { Console.WriteLine("234"); } }}
来源地址:https://blog.csdn.net/m0_46204224/article/details/128875647