C# - 关键字、数据类型
abstract |
as |
base |
|
checked |
|||
event |
|||
internal |
is |
||
override |
|||
sealed |
|||
static |
|||
virtual |
|||
volatile |
- 类型关键字:a.值类型;b.引用类型;c.指针类型;d.void;e.var
- 修饰符:a.访问修饰符;b.abstract;c.asyn;d.const;e.event;f.extern;g.in;h.out;i.override;j.readonly;k.sealed;l.static;m.unsafe;n.virtual;o.volatile
- 语句关键字:a.yield;b.checked;c.unchecked;d.fixed;e.lock
- 方法参数:a.params;b.ref;c.out
- 命名空间关键字:a.namespace;b.using指令;c.using语句
- 运算符关键字:a.as;b.await;c.is;d.new;e.sizeof;f.typeof;g.true,false;h.stackalloc;i.nameof
- 转换关键字:a.explicit;b.implicit;c.operator
- 访问关键字:a.base;b.this
- 文字关键字:a.null;b.default
- 上下文关键字:a.add/remove;b.get;c.global;d.partial类型;e.partial方法;f.set;g.where;h.value;i.yield
关键字是对编译器具有特殊意义的预定义保留标识符。它们不能在程序中用作标识符,除非它们有一个 @ 前缀。
1.类型关键字
值类型的变量存储数据,而引用类型的变量存储对实际数据的引用。引用类型也称为对象。指针类型仅可用于 unsafe 模式。
通过装箱和取消装箱,可以将值类型转换为引用类型,然后再转换回值类型。除了装箱值类型外,无法将引用类型转换为值类型。
a.值类型,基于值类型的变量直接包含值。将一个值类型变量赋给另一个值类型变量时,将复制包含的值。这与引用类型变量的赋值不同,引用类型变量的赋值只复制对对象的引用,而不复制对象本身。与引用类型不同,值类型无法包含 null 值。但是,可以为 null 的类型 功能允许值类型分配给 null,比如int?。
a1.结构(struct),数值类型,整形(sbyte,byte,char,short,ushort,int,uint,long,ulong)、浮点型(float,double)、decimal;
bool;
用户定义的结构。
a2.枚举(enum)
b.引用类型,引用类型的变量存储对其数据(对象)的引用,而值类型的变量直接包含其数据。对于引用类型,两种变量可引用同一对象;因此,对一个变量执行的操作会影响另一个变量所引用的对象。对于值类型,每个变量都具有其自己的数据副本,对一个变量执行的操作不会影响另一个变量(ref 和 out 参数变量除外)。
声明引用类型:class,类只能从一个基类继承实现。 但是,一个类可以实现一个以上的接口。类成员,包括嵌套选件类,可以是 public、protected internal、protected、internal或 private。 默认情况下成员是 private。
interface,接口只包含方法、属性、事件或索引器的签名。 实现接口的类或结构必须实现接口定义中指定的接口成员。
delegate,委托类型的声明与方法签名相似, 有一个返回值和任意数目任意类型的参数。delegate 是一种可用于封装命名或匿名方法的引用类型。 委托类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的。
内置引用类型:
dynamic,该类型的作用是绕过编译时类型检查,改为在运行时解析这些操作。
object,在 C# 的统一类型系统中,所有类型(预定义类型、用户定义类型、引用类型和值类型)都是直接或间接从 Object 继承的。 可以将任何类型的值赋给 object 类型的变量。 将值类型的变量转换为对象的过程称为“装箱”。 将对象类型的变量转换为值类型的过程称为“”。
string,原义字符串以 @ 开头并且也用双引号引起来,不处理转义序列,因此很容易写入。
内插字符串,用于构造字符串。 内插字符串表达式类似于包含表达式的模板字符串。 内插字符串表达式通过将包含的表达式替换为表达式结果的 ToString 表示形式来创建字符串。
c.指针类型,仅可用于 unsafe 模式。https://msdn.microsoft.com/zh-cn/library/y31yhkeb.aspx
不安全代码具有下列属性:
-
方法、类型和可被定义为不安全的代码块。
-
在某些情况下,通过移除数组界限检查,不安全代码可提高应用程序的性能。
-
当调用需要指针的本机函数时,需要使用不安全代码。
-
使用不安全代码将引起安全风险和稳定性风险。
-
在 C# 中,为了编译不安全代码,必须用 unsafe 编译应用程序。
d.void,当用在方法的返回类型,表示不返回值;在不安全上下文中使用 void 将指针声明为未知类型。
e.var,隐式类型。
————————————整形表————————————
————————————浮点型表————————————
————————————默认值表————————————
2.修饰符
a.访问修饰符
public:访问不受限制。
protected:访问仅限于包含类或从包含类派生的类型。
Internal:访问仅限于当前程序集。
protected internal:访问限制到当前程序集或从包含派生的类型的类别。
private:访问仅限于包含类型。
b.abstract,指示所修饰的内容缺少实现或未完全实现。 abstract 修饰符可用于类、方法、属性、索引器和事件。 在类声明中使用 abstract 修饰符以指示某个类只能是其他类的基类。 标记为抽象或包含在抽象类中的成员必须通过从抽象类派生的类来实现。
c.async,可将方法、lambda 表达式或匿名方法指定为异步。如果对方法或表达式使用此修饰符,则其称为异步方法。
d.const,常量可以为数字、布尔值、字符串或 null 引用。
e.event,event 关键字用于在发行者类中声明事件。
f.extern,用于声明在外部实现的方法。 extern 修饰符的常见用法是在使用 Interop 服务调入非托管代码时与 DllImport 特性一起使用。,在这种情况下,还必须将方法声明为 static。extern 关键字还可以定义外部程序集别名,使得可以从单个程序集中引用同一组件的不同版本。
g.in,对于泛型类型参数,in 关键字指定该类型参数是逆变的。 可以在泛型接口和委托中使用 in 关键字。通过逆变,可以使用与泛型参数指定的派生类型相比,派生程度更小的类型。 这样可以对委托类型和实现变体接口的类进行隐式转换。 引用类型支持泛型类型参数中的协变和逆变,但值类型不支持。在泛型接口或委托中,如果类型形参仅用作方法返回类型,而不用于方法实参,则可声明为协变的。 Ref 和 out 参数不能为变体。如果接口具有逆变类型形参,则允许其方法接受与接口类型形参指定的派生类型相比,派生程度更小的类型的实参。 例如,由于在 .NET Framework 4 的 IComparer<T> 接口中,类型 T 是逆变的,因此如果 Employee 继承 Person,则无需使用任何特殊转换方法,就可以将 IComparer(Of Person) 类型的对象指派给 IComparer(Of Employee) 类型的对象。可以向逆变委托分配同一类型的其他委托,但需使用派生程度较小的泛型类型参数。
h.out,对于泛型类型参数,out 关键字指定该类型参数是协变的。 可以在泛型接口和委托中使用 out 关键字。通过协变,可以使用与泛型参数指定的派生类型相比,派生程度更大的类型。 这样可以对委托类型和实现变体接口的类进行隐式转换。 引用类型支持协变和逆变,但值类型不支持。如果接口具有协变类型形参,则允许其方法返回与接口类型形参指定的派生类型相比,派生程度更大的类型的实参。 例如,由于在 .NET Framework 4 的 IEnumerable<T> 接口中,类型 T 是协变的,因此无需使用任何特殊转换方法就可以将 IEnumerabe(Of String) 类型的对象分配给 IEnumerable(Of Object) 类型的对象。可以向协变委托分配同一类型的其他委托,但需使用派生程度较大的泛型类型参数。
(协变和逆变允许数组类型、委托类型和泛型类型参数进行隐式引用转换。)
i.override,要扩展或修改继承的方法、属性、索引器或事件的抽象实现或虚实现,必须使用 override 修饰符。不能重写非虚方法或静态方法。 重写的基方法必须是 virtual、abstract 或 override 的。
j.readonly,readonly 字段可以在声明或构造函数中初始化,readonly 字段可用于运行时常量。const 字段只能在该字段的声明中初始化,const 字段是编译时常量。
k.sealed,当对一个类应用 sealed 修饰符时,此修饰符会阻止其他类从该类继承。
l.static,使用 static 修饰符声明属于类型本身而不是属于特定对象的静态成员。
m.unsafe,表示不安全上下文,该上下文是任何涉及指针的操作所必需的。
n.virtual,用于修饰方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。
o.volatile,指示一个字段可以由多个同时执行的线程修改。 声明为 volatile 的字段不受编译器优化(假定由单个线程访问)的限制。 这样可以确保该字段在任何时间呈现的都是最新的值。volatile 修饰符通常用于由多个线程访问但不使用 lock 语句对访问进行序列化的字段。
3.语句关键字
a.yield,表示所在的方法、运算符或 get 访问器是迭代器。
b.checked,用于对整型算术运算和转换显式启用溢出检查。默认情况下,如果表达式仅包含常数值,且产生的值在目标类型范围之外,则它会导致编译器错误。 如果表达式包含一个或多个非常数值,则编译器不检测溢出。使用 checked 表达式或 checked 块,在运行时检测由前面的求和计算导致的溢出。可以使用 unchecked 关键字阻止溢出检查。
c.unchecked,因为溢出检查比较耗时,所以当无溢出危险时,使用不检查的代码可以提高性能。
d.fixed,禁止垃圾回收器重定位可移动的变量。 fixed 语句只在不安全的上下文中是允许的。 fixed 还可用于创建固定大小缓冲区。
e.lock,将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。lock 关键字可确保当一个线程位于代码的临界区时,另一个线程不会进入该临界区。 如果其他线程尝试进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。
4.方法参数
a.params,可以指定采用数目可变的参数的方法参数。
b.ref,ref 关键字会导致参数通过引用传递,而不是通过值传递。类的成员不能具有仅在 ref 和 out 方面不同的签名。
c.out,通过引用传递参数。这与 ref 关键字相似,只不过 ref 要求在传递之前初始化变量。若要使用 out 参数,方法定义和调用方法均必须显式使用 out 关键字。
5.命名空间关键字
a.namespace,用于声明一组相关对象的大小,可以使用命名空间组织代码元素和创建全局唯一类型。
b.using指令,用于为命名空间创建别名或导入其他命名空间中定义的类型。允许在命名空间中使用类型,这样无需在该命名空间中限定某个类型的使用;允许访问类型的静态成员,而无需限定使用类型名称进行访问;为命名空间或类型创建别名。 这称为 using 别名指令
c.using语句,用于定义一个范围,在此范围的末尾将释放对象,提供能确保正确使用 IDisposable 对象的方便语法。
6.运算符关键字
a.as,执行类型转换在兼容的引用类型或可以为 null 的类型。as 运算符类似于强制转换操作。 但是,因此,如果转换是不可能的,as 返回 null 而不引发异常。as 运算符只执行引用转换、nullable 转换和装箱转换,不能执行其他转换,如用户定义的转换。
b.await,在异步方法应用于任务,以挂起执行方法,直到所等待的任务完成。 这个任务表示正在进行的工作。在其中使用 await 的异步方法必须通过 async 关键字进行修改。使用 async 修饰符定义并且通常包含一个或多个 await 表达式的这类方法称为异步方法。
c.is,检查对象是否与给定类型兼容。如果所提供的表达式非空,并且所提供的对象可以强制转换为所提供的类型而不会导致引发异常,则 is 表达式的计算结果将是 true。is 运算符只考虑引用转换、装箱转换和取消装箱转换。 不考虑其他转换,如用户定义的转换。
d.new,运算符用于创建对象和调用构造函数、创建匿名类型的实例、用于调用值类型的默认构造函数。
在用作声明修饰符时,new 关键字可以显式隐藏从基类继承的成员。 隐藏继承的成员时,该成员的派生版本将替换基类版本。
new 约束指定泛型类声明中的任何类型参数都必须有公共的无参数构造函数。 如果要使用 new 约束,则该类型不能为抽象类型。
e.sizeof,用于获取非托管类型的大小(以字节为单位),包括枚举类型、指针类型,用户定义的结构,不包含任何属于引用类型的字段或属性。
f.typeof,用于获取类型的 System.Type 对象。若要获取表达式的运行时类型,可以使用 .NET Framework 方法 GetType,
g.true,false
h.stackalloc,用于不安全的代码上下文中,以便在堆栈上分配内存块,仅在局部变量的初始值中有效。
i.nameof,用于获取变量、类型或成员的简单(非限定)字符串名称。
7.转换关键字
a.explicit,用于声明必须使用强制转换来调用的用户定义的类型转换运算符。
b.implicit,用于声明隐式的用户定义类型转换运算符。 如果可以确保转换过程不会造成数据丢失,则可使用该关键字在用户定义类型和其他类型之间进行隐式转换。
c.operator,重载内置运算符,或提供类或结构声明中的用户定义转换。
8.访问关键字
a.base,用于从派生类中访问基类的成员,所访问的基类是类声明中指定的基类。
b.this,引用类的当前实例,还可用作扩展方法的第一个参数的修饰符。
9.文字关键字
a.null,表示不引用任何对象的 null 引用的文字值。
b.default,可在 switch 语句或泛型代码中使用。在switch 语句中指定默认标签;在泛型代码中,指定类型参数的默认值,对于引用类型为 null,对于值类型为零。
10.上下文关键字
a.add/remove,add 上下文关键字用于定义一个自定义事件访问器,当客户端代码订阅您的事件时将调用该访问器。如果提供自定义 add 访问器,还必须提供 remove访问器。
b.get,在属性或索引器中定义访问器方法,以检索该属性或该索引器元素的值。
c.global,在 :: 运算符前面使用的 global 上下文关键字引用全局命名空间,该命名空间是任何 C# 程序的默认命名空间,未以其他方式命名。
d.partial类型,分部类型定义允许将类、结构或接口的定义拆分到多个文件中。
e.partial方法,在分部类型的一个部分中定义它的签名,并在该类型的另外一个部分中定义它的实现。类设计人员可以使用分部方法提供由开发人员决定是否实现的方法挂钩(类似于事件处理程序)。如果开发人员没有提供实现,则编译器会在编译时移除签名。下列条件适用于分部方法:分部类型的两个部分中的签名必须匹配;方法必须返回 void;没有允许的访问修饰符。分部方法是隐式私有的。
f.set,在属性或索引器中定义为该属性或索引器元素赋值的访问器方法。
g.where,在泛型类型定义中,where 子句用于指定对下列类型的约束:这些类型可用作泛型声明中定义的类型参数的实参。除了接口约束,where 子句还可以包括基类约束,以指出某个类型必须将指定的类作为基类(或者就是该类本身),才能用作该泛型类型的类型参数。where 子句还可以包括构造函数约束。 可以使用 new 运算符创建类型参数的实例;但类型参数为此必须受构造函数约束 new() 的约束。 new() 约束可以让编译器知道:提供的任何类型参数都必须具有可访问的无参数(或默认)构造函数。
h.value,用在普通属性声明的 set 访问器中。 此关键字类似于方法的输入参数。 关键字 value 引用客户端代码尝试赋给属性的值。
i.yield,在语句中使用 yield 关键字,表示在该关键字所在的方法、运算符或 get 访问器是迭代器。 通过使用 yield 定义迭代器,可在实现自定义集合类型的IEnumerable 和 IEnumerator 模式时无需其他显式类。