我将给你展示如何将你的包含各种类型的源文件变成可以部署的文件, 让我们从检查如下的简单应用程序开始吧:
public sealed class Program {
public static void Main() {
System.Console.WriteLine("Hi");
}
}
这个应用程序定义一个类型Program, 这个类型只有一个公开静态的函数Main, 在Main函数里面有另一个类型的引用, 这个类型是System.Console, System.Console是微软实现的一个类型, 实现这个类型的函数的IL代码位于MSCorLib.dll文件中, 所以我们的应用程序定义了一个类型, 并使用了另外一个公司的类型.
为了构建这个应用程序样本, 将前面的代码放到一个源文件Program.cs中, 然后执行如下的命令:
csc.exe /out:Program.exe /t:exe /r:MSCorLib.dll Program.cs
这个命令行告诉C#编译器产生可执行文件Program.exe(/out:Program.exe). 产生的文件类型是Win32控制台应用程序(/t[arget]:exe).
当C#编译器处理这个源文件的时候, 看上去代码引用了System.Console类型的WriteLine函数, 在这点上,编译器要确保这个类型存在于某个地方, 这个类型有WriteLine函数, 传给这个函数的参数与函数期望的参数相匹配, 因为这个类型没有定义在C#的源文件中, 为了让C#编译器高兴, 你必须给它一组程序集让它使用来解决外部类型引用的问题. 在上面的命令行中, 我已经包含了/r[eference]:MSCorLib.dll开关, 它告诉编译器在由MSCorLib.dll标示的程序集中查找外部类型.
MSCorLib.dll是一个特别的文件, 因为它包含了所有核心类型: Byte, Char, String, Int32和更多的其他类型. 实际上, 这些类型十分常用, 以致于C#编译器会自动地引用MSCorLib.dll程序集. 换句话说, 下面的命令行(省略了/r开关)回合前面的命令行得到相同的结果:
csc.exe /out:Program.exe /t:exe Program.cs
此外, 因为/out:Program.exe和/t:exe命令行开关也是C#编译器默认选择的, 因此下面的命令行也会得到相同的结果:
csc.exe Program.cs
如果由于某种原因, 你不想让C#编译器引用MSCorLib.dll程序集, 你可以使用/nostdlib开关. 微软在构建MSCorLib.dll程序集自身时就使用这个开关. 例如, 当CSC.exe企图编译Program.cs文件时, 下面的命令行将产生一个错误, 因为System.Console类型是在MSCorLib.dll中定义的:
csc.exe /out:Program.exe /t:exe /nostdlib Program.cs
现在, 让我更近地看看C#编译器产生的Program.exe文件, 这个文件到底是什么? 好, 对初学者来说, 它是一个标准的PE(portable executable)文件, 这意味着运行着32位或者64位版本的Windows应该能够载入这个文件,并对其做些事情. Windows支持两类应用程序, 控制台用户接口(CUI)的应用程序和图形用户接口(GUI)的应用程序. 因为我指定了/t:exe开关, 编译器产生CUI应用程序. 你可能会使用/t:winexe开关来让C#编译器产生GUI应用程序.