类库项目
除了在项目中把类放在不同的文件中之外,还可以把它们放在完全不同的项目中。如果一个项目只包含类(以及其他相关的类型定义,但没有入口点),该项目就称为类库。
类库项目编译为 .dll 程序集,在其他项目中添加对类库项目的引用,就可以访问它的内容,这可以是(也可以不是)同一个解决方案的一部分。这扩展好对象提供的封装性,因为修改和更新类库不会影响使用它们的其他项目。这意味着,你可以方便地升级类提供的服务(这会影响多个使用这些类的应用程序)。
下面看一个类库项目的示例和一个利用该类库项目包含的类的独立项目。
试一试:使用类库Ch09ClassLib
和Ch09Ex02\Program.cs
(1)在 C:\BegVCSharp\Chapter09
目录中创建一个 类库
类型的新项目 Ch09ClassLib
,如图 9-7 所示。
图 9-7
(2)把文件 Class1.cs
重命名为 MyExternalClass.cs
(在 解决方案资源管理器
窗口中右击该文件,然后选择 重命名(M)
)。在弹出的对话框中单击 是(Y)
。
(3)MyExternalClass.cs
中的代码随之自动改变,以反映类名的改变:
public class MyExternalClass
{
}
(4)使用文件名 MyInternalClass.cs
给项目添加一个新类。
(5)修改代码,显式地指定类 MyInternalClass
是内部类:
internal class MyInternalClass
{
}
(6)编译项目(注意这个项目没有入口点,所以不能像通常那样运行它—可以选择 生成 | 生成解决方案
菜单项来生成它)。
(7)在 C:\BegVCSharp\Chapter09
目录中创建了一个新的控制台应用程序项目 Ch09Ex02
。
(8)选择 项目(P) | 添加引用(R)
菜单项,或者在 解决方案资源管理器
窗口中右击 引用
,选择相同的选项。
(9)单击 浏览(B)
选项卡,导航到 C:\BegVCSharp\Ch09ClassLib\bin\Debug\
,双击 Ch09ClassLib.dll
。
(10)完成了上述操作后,检查是否已将引用添加到 解决方案资源管理器
窗口中,如图 9-8 所示
。
图 9-8
(11)打开 对象浏览器
窗口,检查新引用,看看其中包含的对象,其结果 如图 9-9 所示
。
图 9-9
(12)修改 Program.cs
中的代码,如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ch09ClassLib;
namespace Ch09Ex02
{
class Program
{
static void Main(string[] args)
{
MyExternalClass myObj = new MyExternalClass();
Console.WriteLine(myObj.ToString());
Console.ReadKey();
}
}
}
示例的说明 这个示例创建了两个项目,一个是类库项目,另一个是控制台应用程序项目。类库项目Ch09ClassLib
包含两个类:MyExternalClass
(可公开访问)和MyInternalClass
(只能在内部访问)。注意 ⚠️,默认情况下,会隐式将类确定为供内部访问,因为它没有访问修饰符。最好明确指定可访问性,因为这会使代码更便于理解,所以指令增加了interanl
关键字。控制台应用程序项目Ch09Ex02
包含利用类库项目的简单代码。 当应用程序使用外部库中定义的类时,可以把该应用程序称为库的客户应用程序。使用所定义的类的代码一般简称为客户代码。
为了使用 Ch09ClassLib
中的类,在控制台应用程序中添加了对 Ch09ClassLib.dll
的引用。对于这个示例,该引用指向类库的输出文件,不过也可以把这个文件复制到 Ch09Ex02
的本地位置上,以便继续开发类库,而不影响控制台应用程序。为用新类库项目替换旧版本的程序集,只需用新生成的 DLL
文件覆盖旧文件即可。
在添加引用后,就可以使用对象浏览器查看可用的类。因为类 MyInternalClass
是内部的,所以在对象浏览器窗口中看不到这个类—它不能由外部的项目访问。但是,MyExternalClass
是可供访问的,这是我们在控制台应用程序中使用的类。
可以把控制台应用程序中的代码替换为使用内部类的代码,如下所示:
static void Main(string[] args)
{
MyInternalClass myObj = new MyInternalClass();
Console.WriteLine(myObj.ToString());
Console.ReadKey();
}
如果试图编译这段代码,就会产生如下编译错误:
`Ch09ClassLib.MyInternalClass` is inaccessible due to its protection level
利用外部程序集中的类的技术是使用 C#和.NET Framework 编程的关键。实际上,使用.NET Framework 中的任何类,也就是在利用外部程序集中的类,因为它们的处理方式是相同的。