1.变量的初始化:
- 变量是类或结构中的字段,如果没有显式初始化,创建这些变量时,其默认值就是0(成员变量)。
- 方法的局部变量必须在代码中显式初始化,之后才能在语句中使用它们的值。
- 实例化一个引用对象需要使用new关键字,使用new关键字把该引用只想存储在堆上的一个对象。
2.类型推断(type inference):使用var关键字。编译器可以根据变量的初始值“推断”变量的类型。
需遵循的规则:
- 变量必须初始化。否则,编译器就没有推断变量类型的依据。
- 初始化器不能为空。
- 初始化器必须放在表达式中。
- 不能把初始化器设置成一个对象,除非在初始化器中创建了一个新对象
3.常量:关键字const
常量具有如下特点:
- 常量必须在声明时初始化。指定了其值后,就不能再改写了。
- 常量的值必须能在编译时用于计算。因此,不能用一个变量中提取的值来初始化常量。如果需要这么做,应使用只读字段。
- 常量总是静态的。但注意 ,不必(实际上,是不允许)在常量声明中包含修饰符static。
4.预定义数据类型
- 值类型
- 引用类型
值类型直接存储其值,而引用类型存储对值的引用。
值类型存储在堆栈中,而引用类型存储在托管堆上。
如果变量是一个引用,就可以把其值设置为null,表示它不引用任何对象。
C#有15个预定义类型(CTS),其中13个是值类型,两个是引用类型(string和object)
5.预定义的值类型
整型:C#支持8个预定义整数类型,分别是:
有符号:sbyte(System.SByte)short(System.Int16)int(System.Int32)long(System.Int64)
无符号:byte(System.Byte)ushort(System.UInt16)uint(System.UInt32)ulong(System.UInt64)
所有整数变量都能被赋予十进制或十六机制的值,后者需要0x前缀。
如果对一个整数是intunitlongulong没有任何显式的声明,则该变量默认为int类型。
浮点类型:C#支持3个预定义浮点类型,分别是:
float(System.Single):32位单精度浮点数(7位)
double(System.Double):64位双精度浮点数(15/16位)
decimal(System.Decimal):128位高精度十进制表示法(28位)
如果在代码中没有对某个非整数值进行硬编码,则编译器一般假定该变量时double.如果想指定为float,可以在其后加上字符F(或f)如:float f = 12.3F;
CTS和C#提供了decimal专业类型进行财务计算,但因为不是基本类型,所以在计算时使用该类型会有性能损失。要指定为decimal,可在其后加上字符M(或m)
bool类型:
bool(System.Boolean):bool值和整数值不能相互隐式转换。
字符类型:
char(System.Char):表示一个16位的(Unicode)字符
6:预定义的引用类型
C#支持两种预定义的引用类型
object(System.Object)
object类型可以用于两个目的:
- 可以使用object引用绑定任何子类型的对象。
- object类型执行许多一般用途的基本方法(但可重写),包括Equals()、GetHashCode()、GetType()、ToString()。
string(System.String)
string与引用类型在常见的操作上有一些区别。例如,字符串是不可改变的。修改一个字符串,就会创建一个全新的string对象,而另一个字符串不发生任何变化。
不能再字符串中使用非转义的反斜杠字符,而需要用两个反斜杠(\)来表示,这就是为什么地址表示用两个反斜杠的原因。(或者使用@)
7:流控制
IF ELSE:对于if,如果条件分支只有一条语句,就无需使用花括号。
SWITCH:case的值必须是常量表达式,不允许使用变量。
如果激活了块中靠前的一条case子句,后面的case子句就不会被激活,除非使用goto语句特别标记也要激活后面的case子句。(但不建议这样使用,代码会非常混乱)
FOREACH: foreach循环不能改变集合中各项的值,否则代码不会编译。如果需要迭代集合中的各项,并改变它们的值,就应使用for循环。
GOTO:goto语句可以直接跳转到程序中用标签指定的另一行(标签是一个标示符,后跟一个冒号),如:goto Lable1;Label1:console.WriteLine("Hello World");
goto有两个限制:不能跳转到像for循环这样的代码块中,也不能跳出类的范围,不能退出try...catch块后面的finally块。
BREAK:break可用于退出for、foreach、while和do...while循环,该语句会使控制流执行和循环后面的语句。
8:枚举
枚举的真正强大之处是它们在后台会实例化为派生于基类System.Enum的结构。这表示可以对它们调用方法,执行有用的任务。在语法上把枚举当做结构式不会造成性能损失。
9:名称空间
可以在名称空间中嵌套其他名称空间,为类型创造层次结构。
注意不允许在另一个嵌套的名称空间中声明多部分的名称空间。
一般可接受格式为CompanyName.ProjectNameSystemSection。
10:名称空间的别名
using 关键字的另一个用途是给类和名称空间指定别名。
注意名称空间别名的修饰符是“:”
using System; using Introduction = Wrox.ProcSharp.Basics; class Test { public static int Main() { Introduction::NamespaceExample NSEX = new Introducition::NamespaceExample(); Console.writeLine(NSEX.GetNamespace()); return 0; } } namespace Wrox.ProCSharp.Basics { class NamespaceExample { public string GetNamespace() { return this.GetType().Namespace; } } }
11.控制台I/O
可以为输出值指定宽度,调整文本在该宽度中的位置,正值表示右对齐,负值表示左对齐。为此,可以使用格式{n,w},其中n是参数索引,w是宽度值
int j = 940; int j = 73; console.WriteLine("{0,4} + {1,4} — {2,4}",i,j,i+j);
预定义类型的主要格式字符串
- C:本地货币格式
- D:十进制格式,把整数转换为以10为基数的数,如果给定一个精度说明符,则加上前导0
- E:科学计数法(指数)格式。精度说明符设置小数位数(默认为6)。格式字符串的大小写(e或E)确定指数符号的大小写
- F:固定点格式,精度说明符设置小数位数,可以为0
- G:普通格式,使用E或F格式取决于哪种格式较简单
- N:数字格式,用逗号表示千分符,例如32 767.44
- P:百分数格式
- X:十六进制格式,精度说明符用于加上前导0
除了e/E之外,格式说明符都不需要考虑大小写
如果要使用格式字符串,应把它放在给出参数格式和字段宽度的标记后面,并用一个冒号把它们分隔开。例如9:C2
最后一个技巧是,可以使用占位符来代替这些格式字符串,如:
double d = 0.234; Console.WriteLine("{0:#.00}",d);
12.C#预处理指令
#define:它告诉编译器存在给定名称的符号
如:#define DEBUG
#undef:与#define正好相反,它删除符号的定义
如:#undef DEBUG
如果符号不存在,则#undef就没有任何作用。同样,如果符号已经存在,则#define也不起作用。
必须把这两个命令放在C#源文件的开头位置,在声明要编译的任何对象的代码之前。
#if,#elif,#else和#endif:这些指令告诉编译器是否要编译某个代码块。与#define结合如下:
int DoSomeWork(double x) { //do something #if DEBUG console.WriteLine("x is " + x); #endif }
这段代码只有在#define定义了符号DEBUG后才执行。否则执行#endif指令,如:
#define ENTERPRISE #define W2K //further on in the file #if ENTERPRISE //do something #if W2K //some code that is only relevant to enterprise //edition running on W2K #endif #elif PROFESSIONAL //do something #else //code for the leaner version #endif
#if和#elif还支持一组逻辑运算符"!"、"=="、"!="和"||",如果符号存在,就被认为是true,否则为false
#warning和#error:
如果编译器遇到#warning指令,会给用户显示#warning指令后面的文本,之后编译继续进行。而#error会退出编译,不会生成IL代码。
使用这两条指令可以检查#define语句是不是做错什么事,使用#warning可以让自己回顾进行了哪些操作。
#line:可以用于改变编译器在警告和错误信息中显示的文件名和行号信息。可以使用#line default把行号还原为默认的行号
#pragma:可以抑制或还原指定的编译警告。
13:标识符
- 标识符区分大小写
- 必须以字母或下划线开头
- 不能把C#关键字用作标识符(如果必须则在前加上@)
C#的约定是命名变量时不使用任何前缀。
14:命名约定
- 类型中所有私有成员字段的名称都应是camel大小写形式,但要注意成员字段的前缀名常常用一条下划线开头。
- 传递给方法的所有参数的名称都应是camel大小写形式。
- camel大小写形式也可以用于区分同名的两个对象—比较常见的情况是属性封装一个字段。