C#从基础到进阶
2024-08-17 14:53:24 6 举报
AI智能生成
这是一份关于C#语言的学习资源,它涵盖了从基础到进阶的所有关键概念。在这里,你将学习到C#的基础语法、数据类型、变量、运算符、条件语句和循环语句等。同时,也会深入探讨面向对象编程的核心思想,如类、对象、继承、封装、多态和抽象等。此外,你还将学习到更高级的主题,如泛型、集合、LINQ、委托和事件等。这是一个全面而系统的学习资料,可以帮助你从C#的初学者成长为高级开发者。
作者其他创作
大纲/内容
初级
数据类型
分类
值类型(Value types)
引用类型(Reference types)
对象(object)类型
动态(Dynamic)类型
字符串(String)类型
指针类型(Pointer types)
可空类型(Nullable)
类型转换
隐式类型转换
这些转换是 C# 默认的以安全方式进行的转换, 不会导致数据丢失。例如,从小的整数类型转换为大的整数类型,从派生类转换为基类。
类型的转换方法:To+类型名
显式类型转换
显式类型转换,即强制类型转换。显式转换需要强制转换运算符,而且强制转换会造成数据丢失。
常量和变量
常量
常量是在程序执行期间不能修改的,可以当作常规变量。
常量是使用 const 关键字来定义的。
const <data_type> <constant_name> = value;
public const int c1 = 5;
变量
运算符
算术运算符
关系运算符
逻辑运算符
位运算符
赋值运算符
其他运算符
判断和循环
判断
if...esle
Switch
循环
循环类型
While
for/foreache
do...while
嵌套多个循环
循环控制语句
Break
终止 loop 或 switch 语句,程序流将继续执行紧接着 loop 或 switch 的下一条语句。
continue
引起循环跳过主体的剩余部分,立即重新开始测试条件。
封装和方法
封装
访问修饰符
public:所有对象可见
private:对象本身在对象内部可以访问
protected:只有该类对象及其子类对象可以访问
internal:同一个程序集的对象可以访问
protected internal:访问限于当前程序集或派生自包含类型
方法
集合
数据(Array)
datatype[] arrayName;
字符串(String)
结构体(Struct)
枚举(Enum)
类(Class)
继承
继承是面向对象程序设计中最重要的概念之一。继承允许我们根据一个类来定义另一个类,这使得创建和维护应用程序变得更容易。同时也有利于重用代码和节省开发时间。
当创建一个类时,程序员不需要完全重新编写新的数据成员和成员函数,只需要设计一个新的类,继承了已有的类的成员即可。这个已有的类被称为的基类,这个新的类被称为派生类。
当创建一个类时,程序员不需要完全重新编写新的数据成员和成员函数,只需要设计一个新的类,继承了已有的类的成员即可。这个已有的类被称为的基类,这个新的类被称为派生类。
多态
多态是同一个行为具有多个不同表现形式或形态的能力。
多态性意味着有多重形式。在面向对象编程范式中,多态性往往表现为"一个接口,多个功能"。
多态性可以是静态的或动态的。在静态多态性中,函数的响应是在编译时发生的。在动态多态性中,函数的响应是在运行时发生的。
多态性意味着有多重形式。在面向对象编程范式中,多态性往往表现为"一个接口,多个功能"。
多态性可以是静态的或动态的。在静态多态性中,函数的响应是在编译时发生的。在动态多态性中,函数的响应是在运行时发生的。
实现多态的方式
静态多态
函数的重载
运算符的重载
动态多态
抽象类:关键字abstract
抽象方法
抽象方法
您不能创建一个抽象类的实例
您不能在一个抽象类的外面声明一个抽象的方法
通过在类的定义前防止关键字sealed,可以将类声明为密封类。当一个类被声明为sealed时,他不能被继承。抽象类不能声明为sealed。
区别
抽象方法:只有方法名称,没有方法体(也就是没有具体实现),子类必须重写父类的抽象方法
虚函数:该方法由方法体,但是子类可以覆盖,也可以不覆盖
虚函数:该方法由方法体,但是子类可以覆盖,也可以不覆盖
虚方法有方法体,抽象方法没有方法体。抽象方法是一种强制派生类覆盖的方法,否则派生类将不能被实例化
抽象方法只能在抽象类中声明,虚方法不是
派生类必须重写抽象类中的抽象方法,虚方法则不必要
虚方法:关键字virtual
当有一个定义在类中的函数需要在继承类中实现时,可以使用虚方法。
虚方法可以在不同的继承类中有不同的实现。
运算符的重载
接口(Interface)
命名空间(namespace)
命名空间的设计目的是提供一种让一组名称与其他名称分隔开的方式。在一个命名空间中声明的类的名称与另一个命名空间中声明的相同的类的名称不冲突。
预处理指令
高级
String类
正则表达式
委托、匿名方法、Lambda和事件
委托和事件
委托
自定义委托
定义:delegate 返回值类型 委托名字(参数类型 参数名字);
示例:private delegate string GetString();
示例:private delegate string GetString();
创建实列:GetString a=new GetString(x.ToString);
GetString a=x.ToString;
说 明:x.ToString就是一个不传递参数并返回string类型的方法。
实例可以当作参数进行传递。
GetString a=x.ToString;
说 明:x.ToString就是一个不传递参数并返回string类型的方法。
实例可以当作参数进行传递。
调用:a();
a.Invoke();
a.Invoke();
系统内置委托类型
Action委托
定义:本身是一个无返回值、无参数的委托类型。
在创建一个委托类型时在Action的后面加上一个泛型就可以成为一个参数为该泛型,没有返回值的委托类型。
示例:Action<Int> a; 这个委托a就是有一个int参数,并且没有返回值的委托。
Action<Int,Int> a; 这个委托a就是有两个int参数,并且没有返回值的委托。
注意:Action最多可以有16个参数
示例:Action<Int> a; 这个委托a就是有一个int参数,并且没有返回值的委托。
Action<Int,Int> a; 这个委托a就是有两个int参数,并且没有返回值的委托。
注意:Action最多可以有16个参数
Func委托
定义:Func中的泛型只有一个时,就代表该委托是一个有返回值,无参数的委托;
Func中有多个泛型时,就代表有返回值(返回值类型是最后一个泛型),有参数(参数类型是前面的所有泛型)的委托;
Func中有多个泛型时,就代表有返回值(返回值类型是最后一个泛型),有参数(参数类型是前面的所有泛型)的委托;
多播委托
定义:就是说一个委托可以引用多个方法,执行顺序为添加方法引用的顺序,并且只能得到最后一个方法的返回值
示例:a+=方法: 委托a加上一个方法的引用
a-=方法; 委托a去掉一个方法的引用
示例:a+=方法: 委托a加上一个方法的引用
a-=方法; 委托a去掉一个方法的引用
获取多播委托中的所有方法并调用
联系和区别:委托可以通过类或者对象在外部进行调用,但是一般也不再外部进行调用;
事件不能通过类或者对象在外部进行调用,都可以在其内部进行调用;
事件和委托在用法上是一样的,本质也是一样的。
事件不能通过类或者对象在外部进行调用,都可以在其内部进行调用;
事件和委托在用法上是一样的,本质也是一样的。
事件
定义:事件是基于委托,是类或者对象向其它类或者对象通知发生的事情的一种特殊签名的委托。
委托和事件在用法上没有区别。
委托和事件在用法上没有区别。
示例:public event 委托类型 事件名称;
Lambda
定义:是用来代替匿名方法的,所以Lambda表达式也是定义一个匿名方法的
示例:lambda表达式不用声明参数类型
注意:lambda表达式中参数只有一个时可以不带小括号(),执行语句只有一个时也可以不带花括号{}或者return;
但是当有多个参数时必须带小括号(),执行语句有多条时必须带花括号{}或者return;
Lambda表达式可以访问外部的参数,,但是用不好容易出错。
但是当有多个参数时必须带小括号(),执行语句有多条时必须带花括号{}或者return;
Lambda表达式可以访问外部的参数,,但是用不好容易出错。
匿名方法
匿名方法实际上是一种将代码块作为委托参数传递的方式,使用这一种方法如果建立新的线程可以减少内存的消耗,匿名方法不声明返回值类型,但是匿名方法的返回值类型必须和委托返回值一样。
查询
LINQ方法
写法
联合查询
排序
扩展方法
写法
后面的方法是lambda表达式的写法,也可以是是写一个方法
联合查询
排序
Join on 集合查询
写法
组外分组、排序
组内属性分组
进程和线程
进程
进程和线程的关系
一个进程包含一个或者多个线程
线程
委托开启线程
当委托有参数是就是加载Null的前面就行
倒数第二个参数是当线程结束时执行的委托(回调函数)
倒数第一个参数是用来给回调函数传递参数的。
倒数第二个参数是当线程结束时执行的委托(回调函数)
倒数第一个参数是用来给回调函数传递参数的。
检测现成的结束
IAsyncResult对象可以接收当前线程的状态。他下面的IsCompleted方法代表当前线程是否执行完毕。
回调函数
参数只有一个IAsyncResult类型的参数
获取线程返回值
a就是一个委托,ar就是线程的状态。
Thread开启线程
创建线程
Thread t= new Thread( Download );//创建 Thread对象出来,这个线程并没有启动,传递的方法也可以是一个对象方法
t.Start();//开启线程
t.Start();//开启线程
传递参数
参数类型必须时Object类型
参数在t.Start(1,"aaa");传递给委托
线程池开启线程
开启工作线程:ThreadPool.QueueUserWorkItem(ThreadMethod);//其中的方法必须有一个Object类型的参数
任务开启线程
创建:Task t = new Task(ThreadMethod);//传递个需要线程去执行的方法
开启
t.Start();
任务工厂
连续任务
如果任务T1依赖于任务T2的完成那么就可以用连续任务来实现。
执行顺序t1然后再到t2和t3
任务的层次结构
我们在一个任务中启动一个新的任务,相当于新的任务是当前任务的子任务,两个任务异步执行,
如果父任务执行完了但是子任务没有执行完,它的状态会设置为WaitingForChildrenToComplete,
只有子任务也执行完了,父任务的状态就变成RunToC ompletion
如果父任务执行完了但是子任务没有执行完,它的状态会设置为WaitingForChildrenToComplete,
只有子任务也执行完了,父任务的状态就变成RunToC ompletion
概念
前台线程
默认情况下Thread创建的线程就是前台线程;
当线程的IsBackGround=true时就代表把当前线程更改为后台线程
当线程的IsBackGround=true时就代表把当前线程更改为后台线程
一个应用的前台线程全部运行结束时会强行终止该应用没有执行完成的后台线程
后台线程
线程池中的线程都是后台线程
线程的优先级
控制线程
问题
争用条件
就是可能多个线程访问或者修改一个变量时造成的不符合逻辑的情况
解决:就是给那个访问或者修改的类的对象加锁。
死锁
就是当去锁定多个对象时,可能会出现多个线程同时锁定多个对象,但是由于锁定顺序的不同,从而造成任何一个线程都无法完成锁定,从而造成死锁。
解决:就是当有多个线程锁定多个对象时,要先确定好锁定的顺序。
Socket类
Tcp协议
UDP协议
0 条评论
下一页