导图社区 Csharp语言基础
Csharp基础,介绍了名称空间、数据类型、变量传参、构成Csharp元素、Csharp语言术语、Csharp内存存储机制等内容,一起来学习吧。
编辑于2023-09-10 14:41:17 广东Csharp语言基础
名称空间
概念:名称空间是程序主体的顶端,以树型结构组织类和其他类型
类库引用
概念:类库引用是使用名称空间的物理基础,引用dll文件或者项目文件使用其名称空间里的类(禁止循环引用类库),引用了类库没有用using引用名称空间的话,需要调用其方法属性事件等信息需要在调用前使用"."来访问
DLL引用
概念:DLL引用也叫黑盒引用,其为别人使用classlibrary构建出来的文件,为无源代码.
项目引用
概念:项目引用可称为白盒引用,引用别人或者自己创建的项目,为有源代码.
数据类型
引用类型
类
概念:类是构成程序的主体,是现实生活中事物进行抽象的结果,类类型关键字:object string.类类型定义关键字:class
类声明位置:1.声明在全局名称空间.2.名称空间.3.声明在类里
类声明: 可选(访问级别修饰符不填则默认internal class 类名{类体} +可选(继承)
示例:public class classname{body;}
对象
概念:对象也叫实例,是类经过实例化后得到的内存实体,创建对象也叫实例化
成员
属性
prop自动生成
概念:属性是一种用于访问对象或类型的特征成员,特征反映了状态(属性是字段的自然扩展) 字段和属性的区别:字段更偏向与实例对象在内存的布局(例如存放运算的数值,因为这些值是没有界限的),属性偏向反应现实生活对象的特征(例如年龄体重ID,因为这些都有界限值的)优点能够保护字段不被非法污染,暴露数据数据存储在字段中,也可以是动态计算出来的,属性是从字段加方法限制来进化而成的,属性的get和set也可以使用修饰符来修饰,也可以实时计算属性的状态(建议永远不要用字段来暴露数据,把字段使用private和protected来封装字段)
示例:字段进化属性的方法:
示例:属性声明:
示例:简略声明:public static int AvgAge { get; set; }
示例:编辑,重构,封装字段也可以声明属性
方法
概念:由C语言的Func进化而来的,表示类或对象"能做什么".描述:方法的由来:前身是C、C++语言的函数,法师面向对象范畴的概念方法永远都是类和结构体的成员(不能独立于类和结构体之外)方法和字段是类最基本的成员本质就是数据和函数.用法:1.隐藏复杂的逻辑2.大算法分解为小算法3.复用
示例:class ClassName{public int FuntionName(int varName,int varName){}}
事件
概念:事件是一种对象或类能够提供通知的成员,通俗来说就是能够发生什么事情.事件的本质是委托字段的一个包装器.事件响应流程:1.我有一个事件2.一个人或者一群人关心我这个事件3.我的事件发生了4.关心事件的人被依次通知5.被通知的人根据数据对事件进行响应
事件模型
事件拥有者
概念:事件的拥有者可以是一个类也可以是一个对象,是存储事件本体的实体
事件成员
概念:事件的成员就是事件本身
事件响应者
概念:事件的响应者就是存放事件处理器本体的实体,事件的响应者也可以是事件的拥有者
事件处理器
概念:事件的处理器是触发事件之后做出对应的处理的方法,它的本质就是一个回调方法
事件订阅
概念:把事件处理器和事件关联起来,本质上就是以委托类型为基础的约定
示例:
另类挂接方式: 1.this.Button.Click += new EventHander(this.ButtonClick); WPF挂接: 2.this.Button.Click += new RoutedEventHandler(this.ButtonClick);
匿名挂接:1.this.Button.Click += delegate(object sender,EventArgs e){事件响应器} 2.this.Button.Click += (ender,e)=>{事件响应器}
建立事件方法
1.事件拥有者和事件响应者分别为两个不相干的类或对象
示例:
2.时间的拥有者和事件响应者是同一个类或对象
示例:
3.事件的拥有者是事件的响应者的一个字段成员
示例:
事件声明
事件是基于委托的,需要委托来做一个约束,它既规定了事件能发送什么消息给事件的响应者,也规定了事件的响应者能收到什么消息,也就是事件响应者处理器必须要和委托匹配才能订阅消息(声明完整事件需要声明的内容包括1.事件的拥有者 2.约束事件的委托(声明委托标识符的规则:name+EventHandle)(独立于类外) 3.存储传递消息的容器(声明消息容器标识符的规则:name+EventArgs)(同时需要消息容器的基类EventArgs) 4.该委托的字段 5.事件 6.事件的响应者 7.事件处理器 8.定义)
实例:
事件意义
事件本质是一个包装器,这个包装器对委托字段起到了限制访问的作用,封装的一个重要作用是隐藏,对外界隐藏了大部分信息,只暴露添加和溢出事件处理器的功能,添加移除事件处理器的时候可以直接使用方法名,这时委托实例不具备的功能
事件委托参数
object
描述:名字叫sender,实质上是事件的拥有者,事件的source
EventArgs
描述:事件的参数容器,给事件传递消息来对应处理事件
构造器
ctor自动生成
概念:构造器分为静态构造器和示例构造器.描述:实例化类的时候就会调用构造器为类的段进行数值初始化每次加载程序进内存的时候开始程序之前都会调用类的静态构造器(静态构造器).使用1.构造器不输入任何标记时调构造器则默认值2.构造器不带参数则初始化默认构造器的标记参数
示例:声明:public classname(int varName1;,int varName2;){properties1 =varName1;properties2 =varName2;} 调用:classname varClass = new classname(properties1num,properties2num);
析构器
概念:与构造器作用差不多,能够在实例回收之后马上调用析构器里的程序
示例: class classname{ ~classname{析构函数}}
字段
概念:字段是一种表示对象或类型关联的变量,与对象关联叫实例字段,与类型关联的字段叫静态字段由static修饰(声明体隶属与类之内,方法之外)
示例:class Student{public int Age;public static int AveAge;}
常量
概念:常量是表示常量值,常量隶属与类而不是对象,所以没有实例常量一说,注意区分成员常量和局部常量,所谓的实例常量由只读实例字段来担当
示例:class classname{public const double PI = 3.1415926; }
索引器
indexer自动生成
概念:它能使对象能够用与数组同样的方式(下标)进行索引(注意没有静态索引器)
示例:
运算符
概念:用于运算的操作的运算符
运算符重载功能操作符重载
嵌套类
概念:把类声明在类体里c成为类的嵌套类(成员类)
示例:namespace{class classname{class classname{}}}
继承
概念:继承的本质是派生类(子类)在完整接收基类(父类)已有成员的基础之上对基类进行横向(对类成员数量的扩充)和纵向(对类成员版本的更新或重写)的扩展
描述:通过继承类在功能上可以得到扩展,子类的访问级别不能超越基类,派生类的基类只能有一个(派生至某个类),但是可以实现多个接口(实现了某个基接口),类的访问等级对继承也是有影响的.一个基类类型的实例可以引用一个派生类的实例.一个派生类实例可以调用一个基类实例的方法属性事件
继承细节:当创建一个派生类实例,实质上是先从父类开始继承下来,所以属性和变量的初始化值都会继承.当使用base去查看基类的值,实质上已经被派生类的值替换了,相当与创建派生类实例的时候基类的信息和派生类的信息都是指向同一个空间
继承构造器细节:派生类构造器的结构要和基类构造器的结构一致且加上:base(基类构造器的形参)
示例:public class BaseClass{ public BaseClass(int reg){}} public class DerivedClass:BaseClass{ public DerivedClass(int reg):base(int reg)}
扩展
重写
描述:派生类对基类成员的重写(由于数量没有增加,只是版本的更新所以是纵向扩展)
声明
格式:,在基类方法使用virtual修饰符,在派生类方法使用override修饰符
示例:基类:public virtual void Run{} 派生类:public overried void Run{}
总结:基类类型变量引用派生类类型的实例-->调用的是派生类的方法
多态
概念:基类类型的变量引用一个派生类类型实例的时候,调用其方法时,方法最终所调用的版本是由对象所决定的,并且一定能调到继承链上最新的版本(变量的类型引用的实例的类型可能不一致造成了多态的效果)
触发重写隐藏条件:函数成员,可见,签名一致
隐藏
描述:外部类调用派生类方法只能看到派生类的同名方法,隐藏了基类的同名方法,实质上派生类有两个方法
格式:派生类和基类使用同一签名,派生类同名方法的前面使用new修饰符(也可以省略)
示例:隐藏父类
总结:基类类型变量引用派生类类型的实例-->调用的是基类的方法
抽象类
概念:抽象类是软件工程的产物,为提高软件工程质量而产生的,一个未完全实现的类,为复用而生
描述:由abstract来修饰,抽象类未实现的方法由派生类来实现,因为抽象类是为重写而生的,所以不支持实例化
格式:abstract class 类标识符{public abstract 方法标识符{}} 引用抽象类跟派生一样和引用抽象方法跟重写一样
示例:abstract class baseclass{public abstract void Func;} public class DerivedClass:BaseClass{public override void Fun{}}
接口
概念:由interface来修饰,抽象类的理念进化而来,其实就是完全未实现逻辑的类(纯虚类).为解耦而生,实现高内聚.低耦合.也是一个协约,不能够实例化接口引用关系图,接口的产生:自底向上(重构),自顶向下(设计)
格式:interface 接口标识符{不带修饰符的方法列表}
示例:interface Interface{ void Add; void Sub; void div; void Mul;}
单元测试
概念:单元测试是项目完成后单独构建测试框架来测试程序预期的效果
流程:1.建立一个xUnitTest或者MSTest的项目 2.引用被测试项目的类库 3.实现被测试项目的基接口 4.在NuGet里安装Moq的类库 5.按照调用流程在测试面板里对项目测试 6.观测测试的结果是否达到预期
示例:
命名规则:单元测试项目的标识符一般取被测试项目的标识符+.test后缀
显示接口成员实现
概念:让类具有两种或以上的性质,使用不同接口的变量来引用类的实例,可以调用不同的函数(Csharp独有的功能)
示例:
委托
概念:委托是函数指针的升级版,把方法体交给委托类型的变量去调用,数据和函数都是一个地址和连续地址的结晶,委托就是把连续地址的函数首地址用委托类型变量封装起来关键字:delegate
直接调用:通过函数名来调用函数,cpu通过函数名直接找到函数所在地址并开始执行->返回
示例:int result = Add(x,y);
间接调用:通过函数指针来调用函数,cpu通过函数指针存储的值获取函数所在地址并开始执行->返回
Csharp自带委托
Action
描述:不带返回值类型的委托
示例:Action<int,int> @Action = new Action<int,int>(Calc.Add);@Action.Invoke(x,y);
Func
描述:带返回值类型的委托
示例:Func<int,int ,int> @Func = new Func<int,int ,int> (Calc.Add);int result = @Func.Invoke(x,y);
自定义委托
描述:自定义委托的声明一定要封装方法的类型兼容,声明在名称空间就是独立的类,声明在类体内就是一个嵌套类
示例:public delegate double Calc(double x,double b); Calc calc = new Calc(Add);
委托一般使用
描述:把方法当作参数传给另一个方法动态调用方法
模板方法
描述:借用指定外部方法产生结果,相当于填空题,常位于代码中部,委托有返回值
回调方法
描述:调用指定的外部方法,相当于流水线,常位于代码末尾,委托没有返回值
示例:
委托缺点:1.委托是一个方法级别的紧耦合.2.可读性下降,debug难度增加.3.把委托回调,异步调用,多线程纠缠在一起很难维护.4.容易造成内存泄漏程序性能下降
高级应用
单播与多播
描述:1.委托单个调用执行程序 2.多个委托叠加到单个委托中,单独调用集成多个委托的单个委托
示例:
同步与异步
描述1.同步调用在一个线程里面逐次调用方法.2.异步调用在多个线程分别调用方法. 串行 == 同步 ==单线程.并行 == 异步 ==多线程进程与线程
示例:
隐式与显式
描述:隐式使用Action.BeginInvoke();显式使用:Thread与Task
示例:显式Thread:
示例:显式Task:
值类型
结构体
概念:结构体关键字是struct.关于结构体类型关键字分别有bool byte char decimal double float int long sbyte short uint ulong ushort
描述:可装拆箱,可实现接口,不能派生自类/结构体.bu'neng'you'xia不能有显式无参构造器
示例:实现接口struct Structname:IStruct{public int ID{get;set;} public string name{get;set;} public void Speak(){body}}
示例:实现有参构造器:struct Structname { public Structname(Tapeparameter) {body} public int ID{get;set;} public string name{get;set;} }
枚举
概念:枚举的关键字是enum,是认为限定取值范围的整数,整数值的对应.
示例:enum enumname{ Drive, Cook, Program, Teach}
比特位式
描述:当需要同时拥有同一个枚举的多个变量时就可以用比特位式,使用二进制描述这个枚举的每个二进制位,把所需要的二进制位组合起来就是表达这个枚举的所有变量
示例:enum enumname{ Drive=1, Cook=2, Program=3, Teach=4} skill = enumname.Drive | enumname.Cook | enumname.Program
泛型
描述:泛型是为了避免成员膨胀和类型膨胀,泛型拥有正交性,与之前所学过的所有数据类型的编程实体都有关联例如:泛型类型(类/接口/委托.....),泛型成员(属性/方法/字段.....)
泛型类
示例:
泛型接口
示例:
泛型方法
示例:
泛化特化
描述:泛化其实就是泛型的声明,把某一个类(泛型类型或者泛型成员)不具体的指向某个数据类型,特化就是泛化的特化,让泛型类型或者泛型成员具体指向某个数据类型,泛化和特化是相对的,泛型的数据类型要在编程的时候特化了之后才能使用特化的泛型都是强类型
静态与非静态
概念:静态成员在语义上表示它是类的成员.实例成员在语义上表示它是对象的成员
类型转换
隐式类型转换
不丢失精度的转换
描述:小存储类型转换成大存储类型 隐式类型转换规则
示例:float value = 10.0;double @double = value;
子类向父类的转换
描述:派生类向基类之间的转换
示例:
装箱
示例:装箱与拆箱
显示类型转换
cast
描述:强制类型转换
示例: (T)x
convert类
描述:C#自带的类型转换的类
示例:double value = System.convert.ToDouble(num);
ToString方法
描述:ToString是object类的方法,obj类是全部类的基类
示例:string value = x.ToString();
Parse/TryParse
Parse
描述:解析当前变量(只能解析正确的格式)
示例:double value = double.Parse(x);
TryParse
描述:尝试解析当前变量,解析错误则返回错误
示例:double value = double.TryParse(x);
拆箱
示例:装箱与拆箱
变量传参
规则:变量名表示变量的值存储的位置,变量的类型表示该变量的存储位置之后的多少空间
变量的种类:1.静态字段 2.实例字段 3.数组元素 4.值参数 5.引用参数 6.输出形参 7.局部变量
数组形参
描述:声明带有params修饰符的数组传参,必须是形参列表中的最后一个(ConsoleWriteLin显示多位参数其实就是带params的数组).小知识string.split(分割符数组)可以把string分割成一个数组
示例:Arraytransmit(5,1,2,3,4,5);调用----->void Arraytransmit(int count,params int array)
示例:分割:string @string = "Tim;Tom.Amy,kretoo";string[]stringarray = @string.split(";" , "." ," ,");
值形参
描述:声明不带修饰符的值参数就是值形参,一个值形参对应一个局部变量,只是该局部变量由调用方法的语句所提供(可以隐式转换) 值类型传参:外部传参进来是复制一个副本,方法内改变值外部不受影响,引用类型传参No new:局部变量引用的是同一个对象 引用类型传参new:局部变量引用的是一个新对象
示例:1.值类型值传参int x = 10;int y = 20;Add(X,Y);调用--->public int Add(int x,int y){} 2.引用类型值传参Form form = new Form;shoudiglog(form)调用--->public void shoudiglog(Form form){} 3.引用类型new值传参Form form = new Form;shoudiglog(form)调用--->public void shoudiglog(Form form){new Form = form}
引用形参
描述:声明带有ref修饰符,与值形参不一样的是引用形参并不创建新的存储位置,表示的是传参进来的同一个存储空间,相当于C语言的传地址调用指针(变量在作为引用形参传递之前必先要明确赋值) 值类型传参:外部传参进来是一个指向外部变量的地址引用,方法内改变值外部也改变.引用类型传参No new:局部变量指向的是旧对象 引用类型传参new:局部变量引用的是新对象但是外部的对象也是指向一个新对象
示例:1.值类型引用传参:int x = 10;调用--->public void changel(ref int x){x = 20;} 2.引用类型引用传参Form form = new Form form.Text = "show";shoudiglog(form)调用--->public void shoudiglog(ref Form form){(form = new Form())form.Text = "showAgain"}
输出形参
描述:声明带有out修饰符,与引用形参一样不创建新的存储空间相当于指针(变量作为输出形参不一定要由明确赋值)但是方法内每一个输出形参都要有明确的赋值.值类型传参:外部传参进来是一个指向外部变量的地址引用,方法内改变值外部也改变.引用类型传参No new:局部变量指向的是旧对象 引用类型传参new:局部变量引用的是新对象但是外部的对象也是指向一个新对象
示例:1.值类型引用传参:int x ;调用--->public void changel(out int x){x = 20;} 2.引用类型引用传参Form form = new Form;shoudiglog(form)调用--->public void shoudiglog(out Form form){(form = new Form())form.Text = "showAgain"}
具名参数
描述:外部调用方法的传参时候标注上方法变量的标识符
示例:int result = Add(x:10,y:20) ;调用----->public int Add(int x,int y){}
可选参数
描述:参数因为具有默认值变得可选,不推荐使用可选参数
示例:int result = Add() ;调用----->public int Add(int x = 10,int y = 20){}
初始化器
概念:可以在新建变量或者实例的时候直接给字段或者变量一个初始值
示例:1.public void name(int name = 0){} 2.class className = new class(){classMember = 0} 3.int[] arrayInt = new int[]{1,2,3,4,5}
构成Csharp元素
标记
概念:编译器能够识别出来有意义的符号
关键字
概念:构成一门基本语言的基础词汇
基本关键字
var
声明
描述:声明隐式类型的变量 临时泛型 引用:new
示例:1.var name = new Form(); 2.var name = 100D;
new
隐藏父类
描述:当使用在派生类的方法中就是隐藏父类的同名方法
示例:
dynamic
弱定义
描述:模仿弱定义关键字,能使变量拥有多种类型,多种类型重复赋值
示例:dynamic myVar = 100; myVar = "Mr.Okey";
const
常量
描述:常量修饰符,修饰数据的常量关键字修饰之后动态不可更改
示例:const int = 0;
static
静态
描述:静态修饰符,字段和方法的修饰符,其与类绑定,加上修饰符则对象不能调用字段和方法
示例:public static int varName;
readonly
只读
描述:只读修饰符,修饰字段和属性的修饰符,修饰之后不能写入数据,静态字段属性只有载入内存的时候调用内部的初静态构造器来初始化数值,非静态字段属性在创建对象的时候通过构造器来初始化,或者通过初始化器来初始化
示例:class Student{public readonly int ID;}
this
类成员
描述:访问当前类的成员信息
示例:this.member;
base
基类成员
描述:访问当前派生类的基类成员信息
示例:base.member;
上下文关键字
value
值
描述:是属性声明的上下文关键字,声明时Csharp内部会从类体外部获取属性的值放到Value中供程序员使用
示例:示例:属性声明:
访问级别关键字
public
公有
描述:可供自身程序集的所有类调用.引用了该类库的程序集也可以调用(访问等级最开放的修饰符)
示例:public class name{}
internal
内部
描述:可供自身程序集的所有类调用.外部访问不到internal级别的类(类声明省略默认internal)
示例:internal class classname{}
protected
受保护
描述:只提供给整条继承链上的lei,非继承链上的类不能访问
实例:protected class classname{}
private
私有
描述:只有自身类成员才能访问,其他类和其他程序集不能访问(属性声明省略默认private)
示例:private class classname{}
sealed
封闭类
描述:使用了sealed修饰符的类是不能够成为别类的基类
示例:sealed class classname{}
操作符
概念:用来表达运算的操作符,本质是函数的简记符.描述:操作符不能脱离与它关联的数据类型(操作符操作的变量是什么类型的操作符就是什么类型).规则:子主题为操作符优先级顺序以上到下,带有赋值功能的表达式都是从右到左,其余都是从左到右
示例:float z = 10f +10f; 此+就是float类型的操作符
基本
x.y
成员访问
描述:可以访问外层名称空间的子名称空间,名称空间的类型,类型的静态成员及对象成员
示例:namespace.class.staticVar
f(x)
方法操作
描述:调用方法及为其输入参数
示例:Add(int,int)
a[x]
访问元素
描述:可访问数组的元素和字典的元素
示例:数组int[] myIntarray = new int[num] 字典:
x++
后置加
描述:当前程序完结后自增
示例:varName++
x--
后置减
描述:当前程序完结后自减
示例:varName--
new
1.实例化类 2.临时泛型
描述:1.创建实例并马上调用其实例构造器 2.临时创建一个结构体(泛型)供调用 3.过多滥用会造成紧耦合
示例:1.Form form = new Form(); new Form(){Text = "hello"}.showdialog(); 2.var varStruct = new{Name = “Kretoo”,ID = 1}; varStruct.Name;varStruct.ID;
typeof
取Metadata信息
描述:取当前类的所有Meadata信息包括(名称空间信息,基类,属性,方法,事件)
示例:
default
置默认状态
描述:把数据类型置为默认状态(注意获取枚举的默认值,如果枚举列表没有0可能会出错)
示例:Form x = default(Form)
checked
检查
描述:用来限定检查数学运算的溢出,只检查不处理错误一般与try--catch同用(Csharp语句里默认都是unchecked需要检测错误时要带checked)
示例:z = checked(x+y); checked{try{body}catch{body}}
unchecked
忽略
描述:用来限定不检查数学运算的溢出
示例:unchecked{try{body}catch{body}}
delegate
匿名方法
描述:一般作为声明委托关键字使用,操作符delegate可以声明临时方法(委托),逐渐被=>取代
示例:iFunc<int,int,int> result = delegate (int x, int y){ return x + y; };
sizeof
获取长度
描述:获取基本数据类型(结构体)或者自定义结构体的数据长度(获取自定义结构体只能放到不安全上下文中) 引用 :指针
示例:unsafe{int x= sizeof(myStruct);}
->
指针访问
描述:C语言一样的指针访问内存,但是Csharp不建议使用指针所以需要把unsafe打开 引用: 指针
示例:unsafe{myStruct* ptr = &struct; myStruct->member = @int;}
一元
+
正
描述:取正数
示例:+x
-
负
描述:取负数
示例:-x
!
非
描述:bool取反
示例:bool @bool = !bool1;
~
按位取反
描述:被操作数据类型的内存二进制值按位取反,注意负数遵循内存存储的源码反码补码原则
示例:int value = ~value;
++x
前置加
描述:执行程序前先自增
示例:++varName
--x
前置减
描述:执行程序前先自减
示例:--varName
(T)x
强制类型转换
描述:把类型转换成其他内容
示例:double(x)
await
描述:略
&x
取地址
描述:把地址传给指针
示例:int* ptr= &count;
*x
解引用
描述:解指针引用地址的值
示例:int @int = *ptr;
乘法
*
乘法
描述:乘法运算
示例:x*y
/
除法
描述:除法运算
示例:x/y
%
取余
描述:除法运算取余数
示例:x%y
加法
+
加法
描述:加法运算
示例:x+y
-
减法
描述:减法运算
示例:x-y
移位
<<
左移
描述:数据类型内存里的变量二进制左移操作(左移一位相当于*2)
示例:byte value = x<<1;
>>
右移
描述:数据类型内存里的变量二进制右移操作(右移一位相当于/2)
示例:byte value = x>>1;
关系和类型检测(bool)
<
小于
描述:检测操作数据是否小于某个数
示例:bool result = x<y;
>
大于
描述:检测操作数据是否大于某个数
示例:bool result = x>y;
<=
小于等于
描述:检测操作数据是否小于等于某个数
示例:bool result = x<=y;
>=
大于等于
描述:检测操作数据是否大于等于某个数
示例:bool result = x>=y;
is
是否
描述:检测变量是否某种类
示例:bool result = x is From;
as
是否(赋值)
描述:检测变量是否某种类是的话就赋值
示例:bool result = x as From;
逻辑"与"
&
与
描述:位与,进行内存里的二进制与操作(有0则0,同1则1)
示例:int value = x&y;
逻辑XOR
^
异或
描述:位异或,进行内存里的二进制异或操作(同则0,异则1)
示例:int value = x^y;
逻辑OR
|
或
描述:位或,进行内存里的二进制或操作(有1则1,同0则0)
示例:int value = x|y;
条件AND
&&
条件与
描述:判断语句真假,全真为真,有假则假
示例:bool result = x>y && a>b;
条件OR
||
条件或
描述:判断语句真假,全假为假,有真则真
示例:bool result = x>y || a>b;
null合并
??
可空值
描述:可空与空值赋值操作符
示例:int? x=null; int value = x??0;
条件
?:
条件赋值
描述:如果符合条件就赋值前者否则赋值后者
示例:string str = x>60?"Pass" : ""Failled;
赋值和lambdab表达式
=
等于
描述:等号表达式运算
示例:int result = x+y;
*=
乘等
描述:乘法操作并赋值表达式运算
示例:int result *= x;
/=
除等
描述:除法操作并赋值表达式运算
示例:int result /= x;
%=
mod等
描述:mod操作并赋值表达式运算
示例:int result %= x;
+=
加等
描述:加法操作并赋值表达式运算
示例:int result += x;
-=
减等
描述:减法操作并赋值表达式运算
示例:int result -= x;
<<=
前移等
描述:前移操作并赋值表达式运算
示例:int result <<= 1;
>>=
后移等
描述:后移操作并赋值表达式运算
示例:int result >>= 1;
&=
与等
描述:与操作并赋值表达式运算
示例:int result &= x;
^=
异或等
描述:异或操作并赋值表达式运算
示例:int result ^= x;
|=
或等
描述:或操作并赋值表达式运算
示例:int result |= x;
=>
lambdab
描述:匿名方法声明简记符,在方法体内声明方法
示例: Func<int,int,int> result = (x, y)=>{ return x + y; };
标准输出转义
$
转义
描述:让ConsoleWriteLine里字符串输入中所有的{}里的变量转义
实例:Console.WriteLine($"....{id}....");
标识符
概念:名称空间,类,变量定义的名称就叫标识符
标识符规范
标识符规范:1.不能与关键字重复但可用@来修饰2.可用汉语3.不能拿数字开头
命名规范
命名规范: 1.类:使用名词 2.属性:使用名词或者复数 3.方法:使用动词或者动词短语 4.事件使用带有时态的动词和短语 5.事件触发的方法on+name 6.字段要用名词 7.字段前加_ 8.接口标识符声明前带I
大小写规范
大小写规范:1.驼峰法:变量名2.帕斯卡法:名称空间,类,方法,事件
标点符号
概念:不参与运算的符号
文本
概念:字面值:整数,实数字符,字符串,布尔,null等
注释与空白
// 与 /**/
表达式
概念:表达式是任何一种语言的基本组件之一(另外还有命令和声明)表达式也是核心组件(专门用来求值的语法实体)(最小的算法元素)得到的结果是SingleValue,Object,Method,Namespace
组成部分
字面值,方法,操作符,操作数,单一值,变量,类型成员,方法参数,名称空间,类型名(以上都有可能组成表达式的一部分)
得到结果
SingleValue(result得到赋值)
示例:int result = 100;
Object(得到一个实体)
示例:(new Form()).ShowDiglog;
Method(myAction得到方法)
示例:Action myAction = new Action(Console.WriteLine);
Namespace(访问对应空间得到空间的类)
示例:System.Windows.Forms.Form maForm = new Form();
表达式分类
A value
A variable
A namespace
A type
A method group
A null literal
A anynymous funtion
A property assess
An event access
An inxder access
Nothing
语句
概念:语句是一种语法实体,就是表达一些即将被执行的动作(最小的独立元素)语句含有自己的内部组件也就是表达式,语句是只有高级语言(贴近人类思维的语言)才有语法,低级语言(贴近硬件的语言)汇编语言与机器语言只有指令(高级语言中的表达式对应低级语言的指令)(一个语句等价于一个或者一组明显逻辑相关的指令)(只出现在函数体里的,出现在类体的程序不叫能语句)
语句分类
声明语句
描述:声明一个或多个变量
格式:声明了数据类型|变量名|可选(初始化器)
示例:1.var reg = 100; 2.int reg = 10;
表达式语句
描述:用于计算所给定的表达式
格式:调用表达式或对象创建表达式或前后置自增自减表达式|;
示例:1.Add(reg,reg); 2.new Form(); 3.x++;
块语句
描述:用于只允许编写单个语句的上下文编写多条语句 技巧:ctrl+} 可以切换在当前块语句前后
格式:{可选(语句列表)}
示例:{statement-list;}
选择语句
if语句
描述:根据要执行表达式的值选择要执行的语句
格式:if(布尔表达式)语句|可选(else语句)
示例:if(result){int reg = 10;}else{int reg =20;}
switch语句
描述:选择一个要执行的语句列表,且有一个相关标签对应switch表达式的值
格式:switch(索引){case 索引编号:break; 可选(default:)}
示例:switch(value){case valueNum: break; case valueNum: break; default:break;}
try语句
描述:用于捕捉块的执行期间发生的各种异常并且在产生异常之后对应的异常类型会产生一个类的实例,可以调用此实例的方法查看异常的信息或者用throw把异常抛出去外层的调用函数处理异常类型
格式:try{检测语句}可选(catch(异常类型){错误处理语句或者throw})可选(finally{必定执行语句})
示例:try{}catch{}finally{}
迭代语句
while语句
描述:按不同条件执行一个嵌入式语句零次或多次
格式:while(布尔表达式){循环体}
示例:while(true){result++; }
do语句
描述:按不同条件执行一个嵌入式语句一次或多次
格式:do{循环体}while(布尔表达式)
示例:do{result++; }while(true)
for语句
描述:计算一个初始化表达式序列,当条件为真则重复调用迭代表达式序列for(;;)无限循环
格式:for(初始化次数;布尔表达式;迭代变量){迭代序列}
示例:for(int i = 0;i<result;i++){;}
foreach语句
描述:用于枚举一个集合的元素并对该集合的每个元素执行一次相关的嵌入式语句,只有实现了IEnumerable接口的类才能被foreach语句迭代
格式:foreach(var 单个集合元素声明 in 集合){迭代序列}
示例:foreach(var result in array){}
跳转语句
break语句
描述:跳出直接封闭它的迭代语句的迭代
格式:循环语句{break;}
实例:while(true){break;}
continue语句
描述:开始直接封闭它的迭代语句的新一次迭代
格式:循环语句{continue;}
示例:while(true){continue;}
goto语句
描述:跳转到标签语句所在的位置
格式:goto(标签);
示例:label: {body} goto label;
return语句
描述:方法体内返回到上层函数,并返回值
格式:return 可选(value);
示例:return value;
throw语句
描述:把捕捉到的异常信息返回到上层函数体
格式:throw 异常信息;
示例:示例:try{}catch{}finally{}
检查语句
checked语句
描述:checked
格式:checked{被检测体}
示例:checked{}
unchecked语句
描述:unchecked
格式:unchecked{忽略检测体}
示例:unchecked{}
标签语句
描述:与goto同使用
格式:标签名:body
示例:label: {body} goto label;
空语句
描述:空,编译器读取时会跳过
using语句
描述:略
yield语句
描述:略
lock语句
描述:用于多线程,略
Csharp语言术语
依赖关系
概念:类或对象之间的耦合关系,优秀的程序追求"高内聚,低耦合"
依赖与耦合
概念:在现实世界做一件事情可能需要多个人,多个人分工合作就是依赖和耦合,转回来虚拟世界来说,类与类之间的分工合作就是依赖,一旦有了依赖就等于有了耦合,依赖越直接耦合越紧
依赖反转
概念:依赖反转就是依赖导致,是SOLID原则之一,实现类与类之间的松耦合,当有多个服务的使用者和多个服务的提供者的时候常规的类实现会使得耦合变紧,依赖反转就是利用接口当作类与类之间的枢纽,去管理类让紧耦合
绑定
概念:指的是编译器把一个成员与类或对象关联起来,"."操作符可以访问成员
强弱类型编程语言
概念:如果数据受到数据类型的约束,则为强类型编程语言,反则亦然为弱类型语言.描述:强类型编程语言:Csharp,弱类型编程语言:C
装箱与拆箱
描述:存储机制:先在stack开辟一个空间存放@int的数据,然后在stack存放一个obj的数据该数据为指向Heap的一个空间,该空间存放@int赋过来的值,然后再开辟一个stack空间存放obj指向的地址的值
装箱与拆箱(Boxing & Unboxing)示例:int @int = 100;obiect obj = @int ;@int = (int)obj;
重载决策
描述:用于方法和构造器给定参数列表和候选函数成员情况下选择最佳函数成员调用
语法糖衣
描述:Csharp为了统一语法,语法简化隐藏一些操作符,例如:在Csharp里类创建实例需要引用到new操作符但是为了和以前C语言的统一在使用int double之类的数据类型隐藏了new(foreach语句 属性声明等都是语法糖,他们隐藏了很多语法;例如:foreach语句隐藏了很多调用迭代器的语法)
例如:int[] intArray = {0,1,2,3,4}; ----->int[] intArray = new int[]{0,1,2,3,4};string name = "Kretoo";----->string name = new string(Kretoo);
数值提升
描述:数值提升也叫数据类型提升,操作符是由数据类型的例如+-*/如果操作数都是int则操作符也是int类型如果其中一个操作数为double则把另一个提升为浮点数再运算操作符也就变成都变了类型
示例:double value = (double)10+10;
变量作用域
描述:在嵌套的块语句里可以访问该块语句外的变量,外层块语句里不能访问里层块语句的变量(基于变量的声明周期)
示例:{int value;{value = 10;}}
只读
只读属性应用场景
为了提高可读性和执行效率------常量
为了防止对象的值被修改------只读字段
向外暴露不允许修改的数据------只读属性(非静态与静态),功能和常量有点重叠
当希望为常量的值其类型不能被常量声明接受时(类/自定义结构体)------静态只读字段
进程与线程
描述:程序开始执行的时候会开始进程,开始的第一个线程为主线程,独立于主线程之外的线程叫分支线程.一般:程序=进程=dx线程((frist = 主线程)+(n*线程 = 分支线程))
程序集
描述:Csharp的每一个类编译之后的结果就是一个程序集(Assembly).dll文件(类库文件)
单根结构
描述:在面向对象的.NET类型系统是单根结构的,单根结构中所有的对象都有一个通用的接口(继承链的顶端),所以它们最终都是属于相同的类型,那就是object类,如果没有使用继承修饰类,则默认就是:class classname : object
继承风格
描述:继承风格有两种:1.class-based(基于类) 例如:Csharp c++ 2.prototype-based(基于原型)例如:javascript
污染名称空间
描述:当不想名称空间有多余的不经常被调用的小方法,可以使用=>来构建匿名委托
Partial类
描述:Csharp编译器允许我们把一个类的代码分成两部分或者多部份来编写,每份都有一个逻辑单元,而且每个逻辑单元按自己进度进行版本更新,Partial可以减少派生类,Partial类合并之后还是原来的类
SOLID设计原则
概念:SOLID:1.单一职责原则(SRP)2.开闭原则(OCP)3.里氏替换原则(LSP)4.接口隔离原则(ISP)5.依赖倒置原则(DIP)
单一职责原则
概念:接口的职责应该单一,不应该承担过多指责
开闭原则
概念:一个软件实体,如类、模块和函数应该对扩展开放,对修改关闭
里氏替换原则
概念:所有父类能出现的地方,子类就可以出现,并且替换了也不会有错误
接口隔离原则
概念:接口的内容一定要尽可能的小,能多小就多小(接口的调用者不能多要)(大接口分裂成小接口)
示例:
示例:
违反接口隔离原则的实例:1.服务的提供者传了一个大接口给服务的使用者.2.服务的使用者设立了一个大接口把符合要求的小接口挡在门外
依赖倒置原则
概念:我们应该面向接口编程,通过抽象成接口,使各个类实现彼此单独,实现类之间松耦合依赖反转
特性
描述:Csharp的特性(Attribute)是由把注释写给人看的转化到写给编译器看的,通过使用打上标记表示此代码的状态
示例:示例:完整项目示例
Csharp内存存储机制
Stack
值类型变量存储机制
描述:当在方法体里新建局部变量之后,新建的变量名(varName)会在stack空闲地址里开辟一个变量类型(int)的空间
示例:public void name{public int varName;}
Stack存储方法调用的变量,数据变量,实例化变量等.Stack技巧:C#开辟Stack方式:int*ptr=stackallo(空间大小);
Heap
引用类型变量存储机制
描述:当在方法体里实例化之后,新建的变量名className会在stack空闲地址里开辟一个指针类型的空间,该指针指向在Heap空间地址开辟的该类型int*2的所有字段staticName varName大小的空间(所以新建两个实例相互赋值其实就是两个指针指向同一个区域)
示例:class name{public static int staticName;public int varName;} public void name{class className = new class();}
Heap存储类实例化的对象等.Heap技巧:手动回收Heap垃圾:winList.Clear();
技巧
指针
描述:C#是不支持使用指针的非要使用的话在设置里把允许不安全函数勾上.
示例:1.在函数声明前加unsafe. 2.在函数体里加unsafe{函数内容}.
方法重载
概念:同方法使用不同的输入输出形参
描述:1.方法签名由方法的名称,类型形参个数类型和种类(值,引用,输出)组成,方法签名不包括返回类型(泛型也可以重载).
示例:声明:public int Add(int,int);public int Add(double,double);
构造器重载
概念:同构造器使用不同的输入输出形参
描述:实例构造函数签名由它每个形参的类型种类组成.
示例:声明:public classname(int,int);public classname(double,double);
操作符重载
概念:把函数定义成操作符,把操作符变成函数的简记法
示例:
自定义类型转换操作符
概念:自定义用户的类型转换,在方法体内遵循某种规则转换
定义隐式类型转换(implicit operator)
示例:
定义显式类型转换(explicit operator)
示例:
迭代器
概念:拥有迭代器的类都是能够迭代的数据类型,迭代器的基接口时IEnumerator,所以只要调用了这个基接口都可以用迭代器
成员
属性Current
描述:存放着集合元素的值
方法MoveNext
描述:当前集合是否遍历完毕
方法Reset
描述:复位迭代器
示例:
索引器
indexer自动生成
概念:它能使对象能够用与数组同样的方式(下标)进行索引(注意没有静态索引器)
示例:
扩展方法
概念:让某一个类拥有另一个类的方法
描述:扩展的方法必须是公有静态修饰的,形参列表第一个必须this修饰,必须由一个静态类(一般命名SomeTypeExtension对SomeType扩展方法) LINQ就是扩展方法实现
示例:
反射
概念:以不变应万变(比依赖反转更松的耦合).反射不是Csharp语言的功能,而是.NET的框架的功能
示例:未封装的反射使用
示例:使用Microsoft.Extensions.DependencyInjection框架的反射
示例:完整项目示例
描述:反射就是使用容器分别封装函数和实例,组合调用
依赖注入
概念:依赖注入是结合了依赖反转结合了接口还有反射的实际应用(依赖反转是概念,依赖注入是应用)需要Microsoft.Extensions.DependencyInjection的类库
流程:1.加载Microsoft.Extensions.DependencyInjection的类库 2.引用其名称空间 3.创建SericeCollection容器 4.为容器AddScoped添加接口和类的动态类型描述 5.BuildServiceProvider注册 6.创建实例来使用反射 (1-5过程是依赖注入的操作 6是使用反射的操作)
优点:1.封装接口和类方便修改,类似C的#define
阅读帮助技巧
异常类型
在每个方法下方的Exceptopns(例外)会描述该方法可能会抛出的各种异常使用try语句可以分门别类的处理异常类型
接口引用关系图
实现方法
override方法
virtual 方法
abstract方法
接口方法
隐式类型转换规则