.NET/.NET Core 的核心就是CLR,CLR与语言无关
.NTE Core由两部分组成:CLR和FCL(Framework Class Libiary)
C#是一种托管语言,会被编译成托管代码(IL),CLR把IL转换成机器的原生代码,JIT(Just-In-Time)编译或Ahead-of-Time编译
托管代码的容器:Assembly 或Portable Executable
创建一个新的C#文件(命令行):dotnet new console --name FirstCSharp
在命令行启动vscode:code .
运行文件:dotnet build----dotnet run
下载第三方库:dotnet restore
dotnet FirstCSharp.dll 这里用到了运行时,C#编译器会把以.cs结尾的源码文件编译成Assembly,这个可以直接运行
值类型与引用类型的根本区别:处理内存的方式
值类型:
包含所有的内置类型(数值、字符、布尔)和自定义的struct和enum
引用类型:
包括所有的class、 数组、delegate、interface 也包括字符串
可以用struct关键字来创建自定义的类型,用此关键字创建的类型,实例化后在进行相互赋值操作,会发生复制,但是这个复制,是复制值,其中一个改变,不会影响到另一个
但是用class关键字创建的类型的对象,相互赋值时,是复制的引用,其中一个改变,会影响到另一个
普通的值类型是不可以为null的,但是C#有一种可空类型(nullable types)来表示值类型的null
多有整数类型都可以被隐式转换成decimal类型,反过来是显式转换
使用checked关键字来检测是否超出类型范围,checked关键字可以作用于变量,语句块,表达式,但是对float 和double是不起作用的
也可以设置最初整个文件都是checked的,命令行/checked+
按位操作符:
按位与:&
按位或:|
异或:^
左移:<<
右移:>>
一些类型没有自己的算数操作符,C#会按需隐式转换到大一点儿的整数类型,比如:byte,sbyte,short,ushort
NaN(not a number),当使用==来比较时,NaN不等于任何一个值,包括NaN
但是,使用object.Equals()时,两个NaN是相等的
Class
readonly修饰符,防止字段在构造之后被改变
readonly字段,只能在声明的时候被赋值,或在构造函数里被赋值 可同时声明多个字段
方法的签名
类型内方法的签名必须唯一
签名:方法名、参数类型(含顺序,但与参数名称和返回类型无关)
EXPRESSION-BODIED方法
比如:int foo(int x){return x * 2;}
可以写成这样:int foo(int x) => x * 2;
或者这样:void foo(int x) =>Console.WriteLine(x);
只适用于单表达式
按值传递还是按引用传递
void Foo(int x) {…}
void Foo(ref int x) {…} 或者void Foo(out int x) {…}
本地方法:在一个方法内部的方法
构造函数里重载:
class和struct可以重载构造函数
当一个构造函数调用重载构造函数时,使用this
当一个类型下的构造函数A调用另一个构造函数B时,B先执行
构造函数和字段的初始化顺序:
字段的初始化在构造函数之前,字段按顺序初始化
DECONSTRUCTOR模式
方法名必须是deconstructor,有一个或多个out参数
继承
子类:父类
AS操作符,会执行向下转换,如果转换失败,不会抛出异常,值会变成null
is操作符会检验引用的转换是否成功
if(子类a is 父类 变量s) //检验a是否是父类的子类,如果是,就将a转换成父类,在赋给变量s
sealed关键字:针对重写的成员,可以使用sealed关键字将其“密封起来”,防止它被其他子类重写
base关键字:和this略像,主要是用于从子类里访问父类被重写的方法;调用父类的构造函数