C# 应用程序结构(程序集, 对象, 成员), 引用程序集与访问限制
应用程序结构(程序集, 对象, 成员)
程序集只是逻辑上的划分, 一个程序集可以只由一个文件组成, 也可由多个文件组成. 不管是单文件程序集还是多文件程序集, 它们都由固定的结构组成. 常见的两种程序集: 可执行文件(.exe文件)和类库文件(.dll文件).
包含应用程序域(AppDomain), 程序集(Assembly), 模块(Module), 类型(Type), 成员(EventInfo, FieldInfo, MethodInfo, PropertyInfo)几个层次. 他们之间是一种从属关系.
派生类可以继承基类的所有成员, 并增加自己的成员来进行功能扩展.
引用程序集与访问限制
引用程序集是一种特殊类型的程序集, 它只包含表示库的公共 API 外围应用所需的最少元数据量. 它们包括在生成工具中引用程序集时所需的所有成员的声明, 但不包括所有成员实现以及对其 API 协定没有明显影响的私有成员的声明. 相比较下, 常规程序集称为“实现程序集”.
在VS开发环境中, 一个解决方案可以包含多个项目, 而每个项目就是一个程序集.
在需要使用另一个程序集时, 不仅需要在代码层面声明使用其命名空间, 在 VS 环境下还需要再项目层面上引用程序集. 因为程序在编译时是以程序集(项目)为单位, 跨程序集(项目)需要在其对应层面上声明. 跨程序集引用的正确姿势是:
- 确保被引用的程序集是可以引用的, 例如项目类型应该是类库, 接口等, 而非控制台应用程序等.
- 在需要引用其他程序集的项目中, 点击 VS 上方项目菜单, 再点击添加项目引用, 勾选需要引用的目标程序集.
- 在需要引用的源代码上方, 使用
using
关键字, 引入引用程序集的目标命名空间.
需要注意的是, internal
成员访问限制的类不可以被外部程序集引用. 下面是一个引用的例子:
被引用的程序集:
namespace Playground
{
public class People
{
...
}
internal class Dean : People
{
...
}
...
}
using Playground;
namespace Program
{
internal class Program
{
static void Main()
{
People testPeople = new People(); // public 可以访问
// Dean testDean = new Dean();
// 错误 CS0122 “Dean”不可访问, 因为它具有一定的保护级别 (internal)
...
}
}
}
上述的public
与internal
是类型访问限制的修饰符, 对于成员来说, 还有成员访问限制修饰符: public
, protected
, private
. 三者的区别如下表所示:
访问类型 | public | protected | private |
---|---|---|---|
内部访问 | 1 | 1 | 1 |
派生类内部访问 | 1 | 1 | 0 |
外部访问 | 1 | 0 | 0 |
使用"人"和"学生"两个类实例演示:
public class People
{
public string Name { get; set; }
protected string tel;
private string id;
}
public class Student : People
{
private float gpa;
public Student(string name, string tel, float gpa)
{
this.Name = name; // 可以访问 (public)
this.tel = tel; // 可以访问 (protected)
// this.id = "test";
// 错误 CS0122 “People.id”不可访问, 因为它具有一定的保护级别 (父类private)
this.gpa = gpa; // 可以访问 (本地private)
}
}
internal class Program
{
static void Main(string[] args)
{
People people = new People();
people.Name = "people0";
// people.tel = "10000";
// 错误 CS0122 “People.tel”不可访问, 因为它具有一定的保护级别 (protected)
// people.id = "42010...";
// 错误 CS0122 “People.id”不可访问, 因为它具有一定的保护级别 (private)
Student student = new Student("people1","10000", 4.5f);
Console.WriteLine(student.Name);
// Console.WriteLine(student.tel);
// 错误 CS0122 “People.tel”不可访问, 因为它具有一定的保护级别 (父类protected)
// Console.WriteLine(student.gpa);
// 错误 CS0122 “Student.gpa”不可访问, 因为它具有一定的保护级别 (private)
...
}
}
基类的保护成员是指允许派生类的方法代码访问, 而不是指通过派生类的对象访问.