技术图文:如何理解C#的internal限制修饰符?

背景

在程序设计领域,面向对象有三大特征:封装、继承、多态。而封装是通过privateprotectedpublicinternal这样的限定修饰符实现的。

我们先来看一下微软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软件技术团队会定期开展提升编程技能的刻意练习活动,希望大家能够参与进来一起刻意练习,一起学习进步!


我是 终身学习者“老马”,一个长期践行“结伴式学习”理念的 中年大叔

我崇尚分享,渴望成长,于2010年创立了“LSGO软件技术团队”,并加入了国内著名的开源组织“Datawhale”,也是“Dre@mtech”、“智能机器人研究中心”和“大数据与哲学社会科学实验室”的一员。

愿我们一起学习,一起进步,相互陪伴,共同成长。

后台回复「搜搜搜」,随机获取电子资源!
欢迎关注,请扫描二维码:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青少年编程备考

感谢您的支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值