本周学习了很多,方法,类等等
方法
方法概念: 一组代码的集合
目的: 方便多次调用, 实现代码重用
定义
c# 里普通函数(方法)必须写在类(或者结构体、记录 record)里面,不能单独写在类外面。
访问修饰符 [其他修饰符] 返回值类型 方法名([参数列表]){ 方法体 }
例子:
定义了一个静态方法,返回两个整数之和
internal class Program { static void Main(string[] args) { int sum = Add(10, 10); Console.WriteLine(sum);//输出20 Console.WriteLine(Add(1,2));//输出3 } static int Add(int a,int b) { return a + b; } }静态方法与非静态方法
静态方法 static
static int Add():属于类本身,不用 new 对象,直接Add()调用实例方法(不带 static)属于实例对象,必须
new出类的对象,才能调用。
例子,定义了一个非静态方法Sub,在Main函数中调用,发生了错误。这是因为static的修饰的函数只能调用静态方法,需要实例对象调用方法才行。
internal class Program { static void Main(string[] args) { int sum = Add(10, 10); Console.WriteLine(sum); Console.WriteLine(Add(1,2)); Console.WriteLine(Sub(7,3));//这里报错 } static int Add(int a,int b) { return a + b; } public int Sub(int a, int b) { return a - b; } }这样使用就行
internal class Program { static void Main(string[] args) { Program program = new Program(); //实例化一个对象 int sum = Add(10, 10); Console.WriteLine(sum); Console.WriteLine(Add(1,2)); Console.WriteLine(program.Sub(7,3));//这样就行,结果为4 } static int Add(int a,int b) { return a + b; } public int Sub(int a, int b) { return a - b; } }当为静态方法时,可以使用类名加.来调用静态方法,不可以使用对象调用,非静态方法还是得使用对象调用
class Calculate { public static int Add(int a,int b) { return a + b; } public int Sub(int a,int b) { return a - b; } } internal class Program { static void Main(string[] args) { Calculate calculate = new Calculate(); //实例化一个对象 int sum = Calculate.Add(10, 10); Console.WriteLine(sum); Console.WriteLine(Calculate.Add(1,2)); Console.WriteLine(calculate.Sub(7,3));//这样就行,结果为4 Console.WriteLine(calculate.Add(44,2));//这样报错 Console.WriteLine(Calculate.Sub(7, 3));//这样也不行 } }总结,就是静态函数可以使用类名.方法名在外边调用,在内部调用则可以直接调用,非静态方法可以在内部非静态函数调用,要做静态函数调用得声明实例一个对象调用。
类
类就是一个模板、图纸,用来描述一类事物有哪些特征、能做什么行为。
定义
class 类名 { // 属性/字段:特征 // 方法:行为 }例子
class Student//定义一个学生类 { private int age;//字段 public int Age//属性 { get { return age; } set { age = value; } } private string name;//字段 public string Name//属性 { get{ return name; } set{ name = value; } } }构造函数
创建对象时自动调用,类中默认会生成一个无参构造函数
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 学习回顾 { class Student//定义一个学生类 { private int age;//字段 public int Age//属性 { get { return age; } set { age = value; } } private string name;//字段 public string Name//属性 { get{ return name; } set{ name = value; } } } internal class Program { static void Main(string[] args) { Student student = new Student();//这里类会生成一个无参数的构造函数初始化实例 } } }也可以自己创建一个构造函数,系统就只会调用自己写的构造函数
class Student//定义一个学生类 { private int age;//字段 public int Age//属性 { get { return age; } set { age = value; } } private string name;//字段 public string Name//属性 { get{ return name; } set{ name = value; } } public Student(int age,string name) { this.age = age; this.name = name; } } internal class Program { static void Main(string[] args) { Student student = new Student();//这里类会报错,因为只会调用自己创建的构造函数 Student student1 = new Student(12, "小米");//这样才行 } }访问修饰符
public:公开,外面可以访问protected:保护的,只能类内部访问,外面访问不到
private:私有,只能类内部访问,外面访问不到
例子
class Student { private string _id; // 私有字段,外部不能直接读取修改 protected int age;//外部不能直接读取修改 public string Name { get; set; } //公开属性 }类的静态成员
可以为静态变量,静态方法
静态方法上面讲了,这里讲静态变量
using System; namespace StaticVarApplication { class StaticVar { public static int num; public void count() { num++; } public int getNum() { return num; } } class StaticTester { static void Main(string[] args) { StaticVar s1 = new StaticVar(); StaticVar s2 = new StaticVar(); s1.count(); s1.count(); s1.count(); s2.count(); s2.count(); s2.count(); Console.WriteLine("s1 的变量 num: {0}", s1.getNum()); Console.WriteLine("s2 的变量 num: {0}", s2.getNum()); Console.ReadKey(); } } }s1 的变量 num: 6 s2 的变量 num: 6
我们可以使用static关键字把类成员定义为静态的。当我们声明一个类成员为静态时,意味着无论有多少个类的对象被创建,只会有一个该静态成员的副本。总之是静态成员是共有的。
方法的重写与重载
方法重载: 在同一个类, 方法名一样, 参数列表不一样的一组方法,称为方法重载
重载(overload):同一个类里面,同名、不同参数,和继承没关系
方法重写: 子类对父类某个方法实现不满意, 子类重写父类这个方法的实现
重写(override)不能改方法签名!签名必须完全一致
方法签名:方法名 + 参数列表(参数个数、类型、顺序,不含返回值、参数名)
特征:
1. 父子类
2. 方法名,参数列表,返回值都一样
3. 方法体实现不一样
C#的重写有两种方式: virtual + override: 虚方法: 父类方法有方法实现的, 子类可以重写,也可以不重写
class Calculate { public virtual int Add(int a,int b) { return a + b; } } class AddNumber:Calculate { public override int Add(int a, int b) { return a-b; } } internal class Program { static void Main(string[] args) { AddNumber addNumber = new AddNumber();//结果-1 Console.WriteLine(addNumber.Add(1,2)); } }abstract + override: 抽象方法, 父类这个抽象方法没有方法体, 子类必须重写这个方法
abstract class Calculate { public abstract int Add(int a, int b); } class AddNumber:Calculate { public override int Add(int a, int b) { return a-b; } } internal class Program { static void Main(string[] args) { AddNumber addNumber = new AddNumber();//结果-1 Console.WriteLine(addNumber.Add(1,2)); } }异常 Exception
异常: 程序在运行时出现的错误, 这个程序可以编译,没有语法错误
编译错误: 代码有语法错误,编译不通过
try-catch
try{ //试一试 //可能产生异常的代码 }catch(异常类型1 异常名){ //捕获 //处理产生异常类型1的 }catch(异常类型2 异常名){ //捕获 //处理产生异常类型2的 }升级版本
try{ //试一试 //可能产生异常的代码 //出现异常代码 //之后代码 }catch(异常类型1 异常名){ //捕获 //处理产生异常类型1的 }catch(异常类型2 异常名){ //捕获 //处理产生异常类型2的 } ... finally{ } //不管是否产生异常,都会执行throw 抛出 语法: throw 异常对象; 可以作为一个返回值
public static int Divide(int num1,int num2) { 返回 if (num2 == 0) { } //使用throw 抛出异常 throw new DivideByZeroException("除数为0"); //throw: 结束方法, 异常作为结果 return num1 / num2; }字典 Dictionary
存储的key/value对, 存储的key与value的映射关系, key唯一, value可以重复
弓 ----- 23
张----- 1021
key,value数据类型可以任意的
泛型字典: Dictionary 推荐
非泛型字典: HashTable
构造方法
属性
例子
常用方法
例子
//方法 //Add() 添加 dict2.Add('m',21); //key不存在, 添加 //dict2.Add('a', 33); //key存在: 抛异常 Console.WriteLine(new string('=',16)); foreach (char k in dict2.Keys) { Console.WriteLine($"key:{k},value:{dict2[k]}"); } //删除 //根据key删除对应键值对 Remove(key) bool flag = dict2.Remove('z'); Console.WriteLine($"删除key为z的键值对是否成功:{flag}"); Console.WriteLine(new string('=', 16)); foreach (char k in dict2.Keys) { Console.WriteLine($"key:{k},value:{dict2[k]}"); } //清空: Clear() //dict2.Clear(); //Console.WriteLine($"字典的元素个数:{dict2.Count}"); //查询: //根据key获取value //第一种方式: 索引器 字典[key] 如果key存在,返回value, 否则抛异常 Console.WriteLine($"key为a的value:{dict2['a']}"); //Console.WriteLine($"key为z的value:{dict2['z']}"); //第二种方式: public bool TryGetValue(TKey key, out TValue value) 如果key存在,返 回value, 否则不抛异常 int val; bool rs = dict2.TryGetValue('a',out val); Console.WriteLine($"key为a的value:{val},rs:{rs}"); rs = dict2.TryGetValue('z', out val); Console.WriteLine($"key为z的value:{val},rs:{rs}"); //判断key是否存在 Console.WriteLine($"dict2字典中是否存在key为a的元素:{dict2.ContainsKey('a')}"); Console.WriteLine($"dict2字典中是否存在key为z的元素:{dict2.ContainsKey('z')}"); //判断value是否存在 Console.WriteLine($"dict2字典中是否存在value为100的元素: {dict2.ContainsValue(100)}"); Console.WriteLine($"dict2字典中是否存在value为1的元素:{dict2.ContainsValue(1)}"); //对字段排序 升序排序OrderBy() 降序排序OrderByDescending() //对字典按照key的升序排序 var rs1 = dict2.OrderBy(kv=>kv.Key); Console.WriteLine(new string('=', 16)); foreach (var item in rs1) { Console.WriteLine($"key:{item.Key},value:{item.Value}"); } //对字典按照value的升序排序 //rs1 = dict2.OrderBy(kv=>kv.Value); //对字典按照value的降序排序 rs1 = dict2.OrderByDescending(kv => kv.Value); Console.WriteLine(new string('=', 16)); foreach (var item in rs1) { Console.WriteLine($"key:{item.Key},value:{item.Value}"); } //遍历字典: 第三种方式, 得到键值对,推荐, 直接遍历字典, 得到是KeyValuePair foreach (var kv in dict2) { Console.WriteLine($"key:{kv.Key},value:{kv.Value}"); }WinForm
Windows窗体应用程序, 图形用户界面(GUI)类库,基于事件驱动
整体这样
工具箱,在视图下面
工具箱里面有很多控件
右边为属性窗口,可以修改控件的属性,添加事件
事件
WInForm布局方式:
第一种方式: 使用Panel + Dock属性(Top,Left,Right,Botton,Fill,None(默认值))
注意: 一个容器中有多个控件, 设置不同Dock的值, 设置Dock为Fill的控件最后添加,最后设置
设置panel位置
设置背景颜色来区分
运行看看
第二种方式: 表格布局 TableLayoutPanel 使用最多
跨列:ColumnSpan=n
跨行: RowSpan= n
第三种布局器: FlowLayoutPanel: 流式布局器, 按照水平, 垂直排列
左到右
上到下
右到左
下到上
常用控件
文本框
Label: 标签, 文本说明
RadioButton: 单选按钮
CheckBox: 复选框, 属性基本一样, 多选
ComboBox: 下拉框
添加成员
运行看看
属性:Items: 添加选项,也可以添加成员
DateTimePicter: 日期时间控件
Timer 定时器
每隔多久,执行一次
方法:
Start(): 开启定时器
Stop(): 停止定时器
DataGridView
最重要的数据展示控件, 支持数据绑定, 以表格形式展示数据
使用步骤:
1. 设置表格的表头(列头定义), 包含一些属性设置
列头的设置 第一种方式
第二种方式: 属性面板--> Columns
2. 绑定数据
第一种方式: 通过手动添加row 了解 通过 DataGridView 的Rows属性(集合属性, 只 读)
第二种方式: 数据绑定
重要 实际开发使用 通过 DataGridView 的 DataSource属性
绑定List集合
绑定DataTable 学习
绑定 BindingSources
先创建一个类存储数据
public class Student { private int age; public int Age { get { return age; } set { age = value; } } private string name; public string Name { get { return name; } set { name = value; } } private DateTime birth; public DateTime Birth { get { return birth; } set { birth = value; } } private int id; public int Id { get { return id; } set { id = value; } } public Student() { } public Student(int id,int age,string name,DateTime dateTime) { this.id = id; this.age = age; this.birth = dateTime; this.name = name; } }添加列
设置列
添加成员
students.Add(new Student(1, 12, "小明", new DateTime(2001, 9, 10))); students.Add(new Student(2, 32, "大明", new DateTime(2002, 7, 10))); students.Add(new Student(3, 42, "张三", new DateTime(2003, 6, 10))); students.Add(new Student(4, 22, "王五", new DateTime(2004, 5, 10))); students.Add(new Student(5, 42, "李四明", new DateTime(2005, 4, 10))); students.Add(new Student(6, 52, "麻子", new DateTime(2001, 3, 10)));绑定数据
运行看看
事件
每个控件都有一个默认事件
如果误操作, 双击,生成默认事件, 不需要事件, 怎么删除?
直接删除事件方法, UI设计器报错
正确做法: 1. 找到控件的事件属性窗口, 把对应的事件绑定的方法,清除
2. 回到窗体.cs代码中,把对应的方法删除,所选内容