背景
在程序设计领域,面向对象有三大特征:封装、继承、多态。而封装是通过private
、protected
、public
、internal
这样的限定修饰符实现的。
我们先来看一下微软CSDN官方对这些限定修饰符的解释:
- private:是允许的最低访问级别,私有成员只有在声明它们的类和结构体中才是可访问的。
- protected:受保护成员在其所在的类中可由派生类实例访问。
- public:类型和类型成员的访问修饰符,是允许的最高访问级别,对访问公共成员没有限制。
- internal:只有在同一程序集的文件中,内部类型或成员才可访问。
我们再来看如下的代码:
// 代码段1
namespace Animal
{
internal class Dog
{
public int Age;
public bool Sex;
}
}
// 代码段2
namespace ConsoleApp
{
using Animal;
class Program
{
static void Main(string[] args)
{
Dog al = new Dog();
al.Age = 20;
Console.WriteLine("Age:{0}", al.Age);
}
}
}
第一段代码和第二段代码定义在同一个项目的不同文件中。
- 第一段代码:在命名空间Animal中,定义了被
internal
限定的Dog
类型。 - 第二段代码:在命名空间ConsoleApp中,首先
using Animal
,之后在Program
的Main方法中使用这个类型。
大家猜测一下,在编译时该段代码会报错吗?要回答这个问题,就要涉及到对internal
这个限定修饰符的理解。
技术分析
internal
,英文含义是“内部的”,这时候基础不扎实的同学,可能就混淆了这个“内部的”的确切含义,到底是指“同一命名空间”的内部,还是“同一程序集”的内部,本人就是突然被问到这个问题的时候,真的就犹豫了,而且曾经一度以为就是“同一命名空间”的内部。
根据上面微软MSDN的解释,其实这个内部就是“同一程序集”的内部,也就是说,internal
修饰的方法或者属性,只要是在同一个程序集中的其他类都可以访问,如果二者不在同一命名空间,只要使用using引用上相应的命名空间即可,这里,从另外一个方面也间接看出命名空间并不是界定访问级别的,而是保证全局的类唯一性的。
程序集的概念:
- 程序集构成了 .NET 应用程序的部署、版本控制、重用、激活范围和安全权限的基本单元。
- 程序集是为协同工作而生成的类型和资源的集合,这些类型和资源构成了一个逻辑功能单元。
- 程序集采用可执行文件 (.exe) 或动态链接库文件 (.dll) 的形式,是 .NET 应用程序的构建基块 。
至此,就能回答上面的问题,在编译时代码不会报错,会输出"Age:20
"。
我们接着看如下的代码:
// 代码段1
namespace Animal
{
internal class Dog
{
public int Age;
public bool Sex;
}
}
// 代码段2
namespace ConsoleApp
{
using Animal;
class Program
{
static void Main(string[] args)
{
Dog al = new Dog();
al.Age = 20;
Console.WriteLine("Age:{0}", al.Age);
}
}
}
第一段代码定义在一个类库(dll)项目中,第二段代码定义在一个控制台应用程序(exe)项目中。
由于两段代码所属的程序集不同,所以第二段代码在编译时会发生错误 “CS0122 “Dog”不可访问,因为它具有一定的保护级别”。
总结
到此为止,我们就把internal
这个限定修饰符介绍完毕了,即internal
在同一个程序集中可以看作是public的,但在不同的程序集中是无法访问的,与是否在同一命名空间无关。好了,今天就到这里吧!See You!
参考文献
- https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/public
- https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/protected
- https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/private
- https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/internal
- https://docs.microsoft.com/zh-cn/dotnet/standard/assembly/index
往期活动
LSGO软件技术团队会定期开展提升编程技能的刻意练习活动,希望大家能够参与进来一起刻意练习,一起学习进步!
- Python基础刻意练习活动即将开启,你参加吗?
- Task01:变量、运算符与数据类型
- Task02:条件与循环
- Task03:列表与元组
- Task04:字符串与序列
- Task05:函数与Lambda表达式
- Task06:字典与集合
- Task07:文件与文件系统
- Task08:异常处理
- Task09:else 与 with 语句
- Task10:类与对象
- Task11:魔法方法
- Task12:模块
我是 终身学习者“老马”,一个长期践行“结伴式学习”理念的 中年大叔。
我崇尚分享,渴望成长,于2010年创立了“LSGO软件技术团队”,并加入了国内著名的开源组织“Datawhale”,也是“Dre@mtech”、“智能机器人研究中心”和“大数据与哲学社会科学实验室”的一员。
愿我们一起学习,一起进步,相互陪伴,共同成长。
后台回复「搜搜搜」,随机获取电子资源!
欢迎关注,请扫描二维码: