名词解释
- CLI Common Language Infrastructure 公共语言基础结构
- CIL Common Intermediate Language 公共中间语言
- BCL Base Class Library 基础类库
- overload 重载:指的是同一个类中有两个或多个名字相同但是参数不同的方法,(注:返回值不能区别函数是否重载),重载没有关键字。
- override 重写 过载:指子类对父类中虚函数或抽象函数的“覆盖”(这也就是有些书将过载翻译为覆盖的原因),但是这种“覆盖”和用new关键字来覆盖是有区别的。
- new 覆盖:指的是不同类中(基类或派生类)有两个或多个返回类型、方法名、参数都相同,但是方法体不同的方法。但是这种覆盖是一种表面上的覆盖,所以也叫隐藏,被覆盖的父类方法是可以调用得到的。
HelloWorld
本书中的例子
1 | class HelloWorld |
其他例子
1 | using System; |
VS IDE自动生成例子
1 | using System; |
语法基础
标识符大小写风格
Pacal风格 (PascalCase/Pascal case)
每个单词首字母大写,例如:ComponentModel, Configuration, and HttpFileCollection. 注意在 HttpFileCollection中,由于首字母缩写词HTTP的长度超过两个字母,所以仅首字母大写。
camel风格 (camelCase/camel Case)
除了第一个字母小写,其他约定与Pascal大小写放个一样,例如:quotient, firstName, httpFileCollection, ioStream, and theDreadPirateRoberts.
形参与实参
1 | namespace ConsoleApplication |
Main
- Main 方法是 C# 控制台应用程序或窗口应用程序的入口点。 (库和服务不要求将 Main 方法作为入口点。) 应用程序启动时,Main 方法是第一个调用的方法。
- C# 程序中只能有一个入口点。 如果您有多个类都包含 Main 方法,则必须使用 /main 编译器选项编译您的程序,以指定用作入口点的 Main 方法。
不带参数
的Main
1 | class Hello |
带参数
的Main
1 | class Hello |
Main 概述
- Main 方法是 .exe 程序的入口点,程序控制流在该处开始和结束。
- Main 在类或结构内声明。 Main 必须是静态的,且不应该是 公用的。 (在前面的示例中,它接受默认访问级别 private。)但不要求封闭类或结构是静态的。
- Main 的返回类型有两种:void 或 int。
- 所声明的 Main 方法可以具有包含命令行实参的 string[] 形参,也可以不具有这样的形参。 使用 Visual Studio 创建 Windows 窗体应用程序时,可以手动添加形参,也可以使用 Environment 类获取命令行实参。 形参读取为从零开始编制索引的命令行实参。 与 C 和 C++ 不同,不会将程序名称视为第一个命令行实参。
Main 例子
1 | class Hello |
编译上面代码,在控制台输入 ==HelloWorld.exe== 输出结果
Hello World!
0
helloworld.exe
D:\WaProj\Essential C#5.0, 4th Edition\第一章
DESKTOP-D10TF3C
ihome
编译上面代码,在控制台输入 ==HelloWorld== 输出结果
Hello World!
0
helloworld
D:\WaProj\Essential C#5.0, 4th Edition\第一章
DESKTOP-D10TF3C
ihome
单行多行语句
一行包含多条语句
1 | System.Console.WriteLine("1");System.Console.WriteLine("2"); |
输出结果
1
2
一条语句跨越多行
1 | System.Console.WriteLine( |
输出结果
Hello World!
错误示例
1 | System.Console.WriteLine("Hello |
错误提示
HelloWorld.cs(5,31): error CS1010: 常量中有换行符
HelloWorld.cs(6,12): error CS1010: 常量中有换行符
缩进和空白
例子1
1 | class Hello |
例子2
1 | class Hello{static void Main(){System.Console.WriteLine("Hello World!");System.Console.ReadKey();}} |
上面两个例子输出结果相同,对编译器来说无差别。
变量声明与赋值
1 | class Hello |
输出结果
Have fun storming the castle!
Think it will work?
It would take a miracle.
We Are Young.
We Are Young.
高级主题:字符串不可变
所有string类型数据,都是不可变的(或者说不可修改的),例如:不可能将字符串“We Are Yong.”修改为“We Are Old.”。也就是说,不能修改变量最初引用的数据,只能重新赋值,让它指向内存中的新位置。
控制台输入输出
从控制台获取输入
使用System.Console.ReadLine()
1 | class Hello |
输出结果
Enter your first name: Jon
Enter your last name: Snow
Hello Jon Snow
高级主题:System.Console.Read()
System.Console.Read()方法返回的是与读取的字符值对应的证书,如果没有更多的字符可用,就返回-1。为了获取实际字符,需要先将证书转型为字符,代码如下:
代码示例 1
1 | class Hello |
System.Console.Read() 从标准输入流读取下一个字符。
System.Console.ReadKey() 获取用户按下的下一个字符或功能键。 按下的键显示在控制台窗口中。
按回车键之前,System.Console.Read()方法不会返回输入,即使用户输入了多个字符。
输入 123,按回车,再输入 a,输出结果
123
1
a
代码示例 2
1 | class Hello |
System.Console.Read() 从标准输入流读取下一个字符。
System.Console.ReadKey() 获取用户按下的下一个字符或功能键。 按下的键显示在控制台窗口中。
按回车键之前,System.Console.Read()方法不会返回输入,即使用户输入了多个字符。
输入 123,按回车,再输入 a,输出结果
123
1
2
3
a
上面两个示例,输入信息相同,由于代码不同因而输出结果不同。
输出到控制台
System.Console.Write() 输出后不添加换行符(当前行终止符)。
System.Console.WriteLine() 将参数内容(后跟当前行终止符)写入标准输出流,输出后,光标切换到下一行。
1 | class Hello |
示例代码中”Hello {0} {1}.”,标识了两个索引占位符,用于在字符串中插入数据。
输出结果
Enter your first name: Jon
Enter your last name: Snow
Hello Jon Snow.
交换索引占位符和对应变量
1 | System.Console.WriteLine( |
输出结果
Enter your first name: Jon
Enter your last name: Snow
Hello Snow, Jon.
代码注释
1 | class Hello |
目前观点
- 不要使用注释,除非代码本身“一言难尽”。
- 要尽量编写清晰的代码,而不是通过注释澄清复杂算法。
CIL和ILDAASM (公共中间语言和IL反汇编)
C#编译器将C#代码转换成CIL代码而不是机器码。对于一个程序集(DLL文件或可执行文件),可以使用CIL反汇编程序将其析构成对应的CIL表示,从而查看其CIL代码。微软的反汇编程序文件:ILDASM(IL Disassembler),可以对程序或者类库执行反汇编,显示由C#编译器生成的CIL代码。
ildasm.exe存在与C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools类似位置
例子
ildasm /text hello.exe
输出结果
1 | D:\WaProj\Essential C#5.0, 4th Edition\第一章>ildasm /text hello.exe |
/text 选项制定输出到命令控制台,而不是在ildasm的图形界面程序中显示。
常见.NET反汇编工具
- dnSpy (免费) 具备调试功能
- ILSpy (免费)
- dotPeek (免费) 生成代码质量较高,Visual Studio风格界面
- .Net Reflector (收费)
为了减少程序被别人轻松反编译,可以考虑使用混淆器(obfuscator)产品。这些混淆器会打开IL代码,将代码加密成一种功能不变但更难于理解的形式。