1.1 创建helloworld
1.1.1 使用文本编辑器和命令行编译器创建
我们先使用Windows自带的记事本程序编写第一个C#程序并使用命令行编译器编译它,以帮助理解C#开发的基本流程。使用记事本(notepad.exe)创建一个新文件,键入(或复制)如代码清单1-1所示的代码,并将文件保存为以.cs后缀结尾的文件名helloworld.cs。
代码清单1-1 helloworld.cs
1: using System; 2: 3: namespace Com.ChinaPub.CSharpMagic 4: { 5: class HelloworldApp 6: { 7: static void Main() 8: { 9: /* 第一个C#程序 */ 10: Console.WriteLine("Hello,world!"); 11: } 12: } 13: }
编译C#源文件需要有.NET SDK,Visual Studio Community安装过程中会自动安装.NET SDK,否则需要单独到微软官网下载.NET SDK安装包。在解释helloworld.cs的代码之前,先依照如下步骤编译并运行。
1)在开始菜单中找到Visual Studio 2017,展开后选择“VS 2017的开发人员命令提示符”(英文版:Developer Command Prompt for VS2017),如图1-3所示。
图1-3 打开VS命令行
输入cd命令,将当期工作目录切换到hello-world.cs所在的文件夹,如果helloworld.cs所在的驱动器不在C盘,需要加/d选项进行驱动器切换操作,如笔者的示例代码在D盘,使用下列命令可切换工作目录:cd /d D:\workspace\华章写书\C#编程魔法书\src\示例代码\第一章。
2)编译C#源文件的程序是csc.exe,它可以同时编译多个源文件,还支持通过很多选项来修改编译过程。这里我们使用最基本的命令编译程序:
csc helloworld.cs
3)编译成功的话,除了编译器默认输出的版本和版权信息外,不会有任何其他消息出现。成功后生成的helloworld.exe保存在当前文件夹,也就是helloworld.cs所在的文件夹,输入如下命令可执行程序:
helloworld.exe
4)如果一切顺利的话,你应该可以看到图1-4所示结果。
图1-4 helloworld程序的运行结果
5)如果源文件有编译错误,csc.exe编译器会报告错误的位置,如图1-5所示。
图1-5 helloworld编译过程常见错误
第1行错误消息“helloworld.cs(9,21):error CS0117……”指明了发生编译错误的源文件是helloworld.cs,错误代码具体的位置是第9行第21列。紧跟在后面的CS0117是错误消息代码,使用搜索引擎搜索这个错误代码可以查到C#官方文档上对该错误的解释和相应的解决方案。错误代码后面的则是具体的错误消息,说明出现编译错误的原因。
第2行错误消息没有指明发生错误的源文件和相应的源码位置,这是因为csc.exe编译C#代码分两个过程:编译和链接。第1行的错误发生在编译过程中,也叫编译错误,编译器csc.exe有具体的源码信息;第2行的错误发生在链接过程,编译器csc.exe已经没有源码信息了,只能报告具体的错误,但是无法给出行号。编译过程和链接过程将分别在后文探讨。
C#语言是大小写敏感的语言,初学者很容易犯的错误是将大小写混用,如Main方法写成了main,WriteLine方法写成了Writeline。单词拼写错误也是初学者容易犯的错误,如果编译过程编译器报告错误,请检查是否犯了这里说的两个错误。
1.1.2 使用Visual Studio Community创建
记事本和命令行编译器csc.exe等工具只适合编写极小规模的程序,要编写商业化应用,推荐读者使用Visual Studio这样的集成开发环境,以简化日常的开发工作。本节介绍使用Visual Studio Community创建helloworld程序的方法。
1)启动Visual Studio 2017,并依次点击菜单栏中的“文件”→“新建”→“项目”命令,打开“新建项目”对话框。
2)在“新建项目”对话框左侧的“已安装”树形列表中选择Visual C#,接下来在右侧的列表中选择“控制台应用”(.NET框架),然后在下侧的“名称”文本框里输入工程名helloworldvs,并在“位置”下拉框里选择保存工程的文件夹,如图1-6所示。
图1-6 新建helloworld工程
3)点击“确定”按钮创建工程,将默认Program.cs文件中的内容替换成代码清单1-1中所示的代码。
4)在代码的第10行的最左侧灰色区域点击一下,设置一个断点,再点击工具栏中的“启动”按钮,或者按键盘上的F5按钮启动编译并执行生成后的程序,如图1-7所示。
图1-7 设置断点并执行代码
5)程序运行起来后,会自动切换回Visual Studio,并在第10行中断执行,点击工具栏的“继续”按钮继续执行程序直到退出,如图1-8所示。
图1-8 Visual Studio里中断后继续执行程序
6)因为程序只是打印一行文字,这个过程对于计算机来说太快了,所以前面通过设置断点的方式中断程序执行,以便读者看到程序运行效果。Visual Studio还提供了另外一种执行方式:同时按下键盘上的Ctrl + F5组合键,可以在程序执行完毕后不关闭命令行窗口,以便开发人员看到运行效果,然后按下任意键即可关闭打开的命令行窗口并回到Visual Studio界面。
1.1.3 helloworld源码解读
C#命令行程序必须包含唯一的主入口方法。它是整个程序的入口和结束的地方,在主入口方法里可以创建对象并调用其他方法来完成代码执行,这一点与C、C++和Java等语言类似。这个方法的名称默认是Main,必须定义在一个类型或者结构体里,且是一个静态方法。
1)代码清单1-1中第3行使用namespace关键字定义了一个名为Com.ChinaPub.CSharpMagic的命名空间。命名空间是可选的,其作用类似域名——为程序定义一个全球唯一的名字。如前面我们使用记事本团队开发的程序编写代码,而记事本开发团队又依赖Windows团队开发的Windows文件管理模块将代码保存到磁盘上,接下来我们又使用编译器团队开发的编译器将文本形式的代码转换成可执行的二进制程序。每个程序都有一个名字,众多开发团队编写的程序难免有重名,这样使用命名空间来避免重名就显得很有必要。一般来说,命名空间的命名规则跟域名类似,只不过是倒过来的,如开发团队(公司)的网站域名是china-pub.com,那命名空间一般会定义成Com.ChinaPub,这里单词字母的大小写依据的是C#的编码规范,在第3章会讲解C#的编码规范。
2)代码清单1-1中第5行定义了一个类型:HelloworldApp,程序的Main方法就包含在这个类型里。如果读者有Java编程经验,会注意到C#与Java稍有不同,C#不像Java那样要求源文件名必须和类型名相同,这在编写代码时给程序员提供了一些便利。第6行至第11行两个大括号包含起来的代码定义了类型HelloworldApp的主体,其只包含一个成员——Main方法。
3)代码清单1-1中第7行定义了入口Main方法,这里再次请读者注意,特别是有C/C++和Java背景的读者,C#语言里的入口方法名是Main(大写的M),而不是main(小写的m)。static关键字设定的Main方法是一个静态方法。静态方法与其他方法的区别将在第2章说明。void关键字指明了Main方法没有返回值,Main方法也可以返回一个整型数值。例如,当Main方法返回整型数值时,一般是在外部环境,特别是在启动C#进程的进程返回程序中。在Developer Command Prompt for VS2017控制台程序里执行外部进程也可以在启动C#进程时传递一些数据(参数)。
4)代码清单1-1中第8~11行的大括号包含Main方法的代码——向命令行输出一行文字:Hello,world!。程序使用了微软.NET开发团队提供的封装了命令行功能的Console类型,其WriteLine方法的作用就是在命令行输出一行指定的字符串文本。Console类型在命名空间System里定义。要想在程序里使用它,需在第1行通过using关键字将其引入。
1.1.4 C#脚本语言
Visual Studio里附带了程序csi.exe,允许用户采用交互的工作方式执行C#代码,达到类似脚本语言的所见即所得效果。
1)打开“VS 2017的开发人员命令提示符”,输入csi命令。
2)在看到“>”提示符后,键入代码清单1-2的代码。
代码清单1-2 解释执行helloworld.csi代码
System.Console.WriteLine("Hello,world!");
3)敲回车完成代码执行,如图1-9所示。
图1-9 使用csi解释执行C#代码
4)按下CTRL + C组合键关闭csi程序。
5)将代码清单1-2的代码保存到文件helloworld.csi中,使用csi.exe执行C#代码,如图1-10所示。
图1-10 使用csi.exe执行C#代码