Csharp-notes

C# 基础

一、C#语言及其特点

二、认识.NET Framework和.NET Core

.NET是什么

.NET和C#的关系,这是初学者最常见的问题

三、Visual Studio 2019的安装与使用

简介

Mirosoft Visual Studio(简称VS)是美国微软公司的开发工具包系列产品。VS是一个基本完整的开发工具集。是编写C#程序或者说.NET程序最常用的开发工具。因其功能强大、简单易用、速度快、智能度高。被网友戏称宇宙第一IDE

  1. 下载地址:https://visualstudio.microsoft.com/zh-hans/free-developer-offers/

  2. VS安装,此时需要联网

  3. 根据自己的情况选择需要的安装模块,一般选择“ASP.NET开发”、“.NET桌面开发”、“通用Windows平台开发”、“数据库存储和处理”、“Visual Studio扩展开发”、“.NET Core跨平台开发”

  4. 点击安装即可开始创建第一个项目

四、C#语法基础

cs文件结构

结构展示

  1. 程序的第一行using System; using关键字用于在程序中包含System命名空间。一个程序一般有多个using语句

  2. 下一行是namespace声明。一个namespace是一系列的类。 WebApplication1 命名空间包含了类Program

  3. 下一行是class声明。类Program包含了程序使用的数据和方法声明。类-般包含多个方法。 方法定义了类的行为。在这里,Program类只有一 个Main方法。

  4. 下一行定义了Main方法,是所有C#程序的入口点。Main方法说明当执行时类将做什么动作。

  5. Main方法通过方法体中的语句指定它的行为。

C#基本语法

注意:

C#是一种面向对象的编程语言。在面向对象的程序设计方法中,程序由各种对象组成。相同种类的对象通常具有相同的类型。

案例: 以人类为例,从人类中诞生出的具体对象“C罗”和“梅西”,同属人类,故俩人类型相同。

关键字

关键字,是对编译器有特殊意义预定义保留标示符,它们不能在程序中用作标示符

铭记:

  1. 不写注释是流氓
  2. 名字瞎起是扯淡
  3. 相比注销,注释意义更大
  4. 要做到别人一看就能看懂

变量

五、C#语法进阶

表达式

类别 表达式 说明
基本 x.m 成员访问
  x(...) 方法和委托调用
  x[...] 数组和索引器访问
  newT(...) 对象和委托创建
  newT(...){...} 使用初始值设定项创建对象
  new{...} 匿名对象初始值设定项
  newT[...] 数组创建
一元 +x 恒等
  -x 求相反数
  !x 逻辑求反
  ~x 按位求反
  ++x 前增量
  --x 前减量
  x++ 后增量
  x-- 后减量
  (T)x 将x显示转换为类型T
二元 x * y 乘法
  x / y 除法
  x % y 取余
  x + y 加法,字符串串联
  x - y 减法
  x << y 位左移
  x >> y 位右移
  x < y 小于
  x > y 大于
  x <= y 小于或等于
  x >= y 大于或等于
  x is T 如果 x 位 T ,返回true,否则false
  x as T 返回转换为类型 T 的 x ,如果 x 不是 T 则返回null
  x == y 等于
  x != y 不等于
  x & y 整形按位与 ,布尔逻辑AND
  x | y 整形按位或 ,布尔逻辑OR
  x && y 且,当 x 为true时,才对 y 求值
  x || y 或,当 x 为false时。才对 y 求值
  x ?? y 如果 x 为null,则计算结果为 y,否则为 x
三元 x ? y : z 如果 x 为true,对 y 求值,x 为false,对 z 求值
赋值或匿名函数 x = y 赋值
  x = x + y 复合赋值
  (T x) => y 匿名函数(lambda表达式)

分支语句

if 语句

if-else 语句

switch 语句

循环语句

for循环
for(int i = 0; i<10;i++ ){     }           
while循环
while(true){  }
do-while循环
do{  }while(true)

数组

数组的声明

//声明没有元素的数组     
int[] ints = new int[6]     
//声明初始化有元素的数组     
int[] ints = new int[]{1, 3, 4, 5}     
//在声明初始化有元素的数组时,也可以指定数组大小     
string[] strings = new int[5]{"H", “E", "L",“L","0"}

通过索引获取数组中的元素。

//声明初始化有元素的数组  
int[] ints = new int[]{1, 3,4,5}  
//获取数组中第1个的元素。
int i1 = ints[0];  
//给数组内的元素赋值
ints[0]  = 1  

总结提升

案例一:老公买西瓜系列
思考
总结
扩展
String st="5.21";
double n=5.21;
Int . Parse(st);//输出5
Int .Parse(n);//报错

对比下面的例子:

Console.WriteLine(Convert.ToInt32(4.3));//四舍五入,输出4
Console.WriteLine(Convert.ToInt32(4.5));//第一位小数为5时,4. 5在4和5之间,输出偶数4 
Console.WriteLine(Convert.ToInt32(4.53)); //四舍五入,输出5
Console.WriteLine(Convert.ToInt32(5.3));//四舍五入,输出5
Console.WriteLine(Convert.ToInt32(5.5)); //第一位小数为5时,5.5在5和6之间,输出偶数6 
Console.WriteLine(Convert.ToInt32(5.53)); //四舍五入,输出6

注意:ConvertToInt32()int.Parse()对于空值(null)的处理不同,ConvertToInt32(null)会返回0而不会产生任何异常,但int.Parse(null)则会产生异常。

案例二:班级找赵六系列
思考
总结

函数初识

函数的命名规范

Add();
AddCount();
GetUsrInfo();

函数的参数设置&传参行为

函数返回值的设置

拓展– 参数修饰符

修饰符种类

  1. 无修饰符:如果一个参数没有用参数修饰符标记,则认为它将按值进行传递,这将意味着被调用的方法收到原始数据的一份副本

  2. out: 输出参数由被调用的方法赋值,因此按引用传递,如果被调用的方法没有给输出参数赋值,就会出现编译错误,也就是说,只要调用了,就必须给赋值。out 最大的用途就是调用者只使用一次方法的调用就能获得多个返回值。(在C#7.0中要实现一次方法的调用就能获得多个返回值,建议使用元组。是元组不是元祖),调用的是指针,是地址

  3. ref: 调用者赋初值,并且可以由被调用的方法可选的重新赋值(数据是按引用传递的)。如果被调用的方法未能给ref参数赋值,也不会有编译器错误。

  4. 了解即可params:这个参数修饰符允许将一组可变的数量的参数作为单独的逻辑参数进行传递, 方法只能有一个params修饰符,而且必须是方法的最后一个参数。

  5. outref的区别

    • out修饰的参数必须在方法内修改,而ref可以修改也可以不修改;

    • out在传入参数的时候,参数是局部变量的话,可以不用赋值,因为out一定会对其进行赋值;

    • ref修饰的参数,在实参必须有初始值才能调用。因为ref修饰的不一定会给它赋值。

六、面向对象(OOP)基本概念

面向对象编程—Object Oriented Programming 简写 OOP

目标

01.面向对象基本概念

1.1 过程和函数(科普)

1.2 面向过程和面向对象基本概念

1.2.1 面向过程—怎么做?
1. 把完成某一个需求的所有步骤从头到尾 逐步实现

2. 根据开发需求,将某些功能独泣的代码封装成一个又一个函数

3. 最后完成的代码,就是顺序的调用不同的函数
面向过程的特点
  1. 注重步骤与过程,不注重职责分工

  2. 如果需求复杂,代码会变得很复杂

  3. 复杂项目,没有固定的套路,难度很大!

1.2.2 面向对象—谁来做

相比较函数, 面向对象是更大的封裝,根据职责,在一个对象中封裝多个方法

  1. 在完成某一个需求前,首先确定职责,要做的事情(方法)

  2. 根据职责确定不同的对象,在对象内部封装不同的方法(多个)

  3. 最后完成代码,就是顺序的让不同的对象调用不同的方法、

面向对象的特点
  1. 注重对象和职责,不同的对象承担不同的职责

  2. 更加适合应对复杂的需求变化,题门应对复杂项目开发,提供固定套路

  3. 要在面向过程基础上,学习些面向对象的语法

七、类和对象

目标

01.类和对象的概念

对象是面向对象编程的两个核心概念

1.1 类

1.2 对象

在程序开发中,应先有类,再有对象

02.类和对象的关系

03.类的设计

在使用面向对象开发前,应该首先分析需求,确定一下程序中需要包含哪些类

在程序开发中要设计一个类,通常需要满足以下三个要素:

  1. 类名这类事物的名称,满足大驼峰命名法

  2. 属性这类事物具有什么样的特征

  3. 方法这类事物具有什么样的行为

3.1 类名的确定

名词提炼法分析整个业务流程,出现的名词,通常就是找到的类。

3.2 属性和方法的确定

提示:需求没有涉及的属性或者方法在设计类时,不需要考虑

练习1

需求
类名
属性 名字,年龄,身高
方法 跑步(), 吃()

练习2

需求
类名 怪兽
属性 名字,颜色
方法 喷火(), 发射激光()

04.类和对象的使用

4.1 声明类

public class Person{

}

4.2 声明属性

4.3 声明方法

详见函数初识

4.4 实例化

4.5 知识拓展

访问修饰符
访问修饰符:
访问级别约束:

注意: 类的访问级别默认为隐式私有需要加上public 才可让外部访问

静态方法、 属性

静态类

十、集合&字典的初识

01.集合的使用

1.1 数组的优劣分析

优势
劣势

1.2 ArrayList的使用

ArrayList的优势
ArrayList arrayList=new ArrayList();
arrayList.Add(123);		//将数据新增到集合结尾处
arrayList.Add("abc");	//将数据新增到集合结尾处
arrayList[2]=345;     	//修改指定索引的数据
arrayList.RemoveAT(0);  //移除指定索引处的数据
arrayList.Remove(123);  //移除内容为123的数据
arrayList.Insert(0,"hello world");    //再指定索引处插入数据

从上面示例看,ArrayList好像是解决了数组中所有的缺点,那么它应该就是完美的。可是在C#2.0后又会出现了List集合,这是为何?

ArrayList的劣势

1.3 装箱与拆箱的概念

int i = 123;
object o= 1;  
object o=123;
int i = (int)o;  

1.4 List集合

List集台的声明

所谓接口目前可以简单理解成限制和规定类型行为类型方法的一种手段

List<int> list = new List<int>();   // 第一种初始化方式
list.Add(123);      // 新增数据到结尾处
List<int>  intList = new List<int>  // 第二种初始化方式
{
    123,
    456,
    789
};
intList[2] = 345;
intList.RemoveAt(0);    // 删除指定索引处的数据
intList.Remove(123);    // 删除内容为123的数据
intList.Insert(0, 6688);

上例中如果我们往List集合中插入string宇符”hello world”,系统就会报错,且不能通过编译。这样就避免了前面讲的类型安全问题与装箱拆箱的性能问题

思考
总结

02. Dictionary字典的使用

键与值可以是任何类型,但是键必须在设置时是唯一的,而值可以不唯一,就好比每个学生的学号必须是唯一的,而所有的成绩可以不唯一。

Dictionary<int, string> dictionary = new Dictionary<int,  string>();
//两种赋值方式  
// 方  式 一 :Add 方 法 赋 值 
dictionary.Add(1, "98分"); 
dictionary.Add(2, "92分");  
dictionary.Add(3, "89分"); 
dictionary.Add(1, "88分");	//系统会报错  
//方式二:索引器赋值  
dictionary[1] = "88分";		//系统不会报错
dictionary[4]  = "99分";  
//方式三:对象初始化器  
Dictionary<string, string> dictionary2 = new  Dictionary<string, string>()  {
	{"A","aa" },  
	{"B","BB" },  
	{"C","CC" }  
};  

注意dictionary[1]方式既可以赋新值可以修改原来已键有的值,类似于数组索引器的使用, 所以可以使用之前已使用过的键。但是Add方法不可以添加已有键的值。

//获取键为1的值  
//方式一:索引器取值  
string value = dictionary[1];  
//方式二:foreach遍历取值  
foreach (KeyValuePair<string, string> item in dictionary) {  
    int key  = item.Key; 
	string value = item.Value;  
}  
//移除键为1的键值对
dictionary.Remove(1);

总结

03. foreach的使用

3.1 foreach操作数组

int[] ints= {123456};
foreach (int item in ints){  //每次循环,其item都是整型数组中的一个元素  } 

3.2 foreach操作集合

List<int> intList = new  List<int>() { 1, 2,3, 4,5, 6 }; 
foreach (int item in ints){  //每次循环,其item都是List集合中的一个元素  }

3.3 foreach操作字典

Dictionary<string, string> dictionary = new Dictionary<string,  string>() {  
    { "A","aa"}, 
    { "B","bb"}, 
    { "C","cc"},
};  
foreach  (KeyValuePair<int, string> item  in dictionary) {
    int key  = item.Key; 
	string value =  item.Value; 
}