news 2026/10/27 1:00:44

C# 访问修饰符详解:public、protected 与 private

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C# 访问修饰符详解:public、protected 与 private

在 C# 中有一条重要的访问控制规则:编译器不允许派生类的可访问性高于其基类。也就是说,内部类可以继承自一个公共类,但公共类不能继承自一个内部类。

本文围绕 C# 中最常用的三个访问修饰符——public、protected和private——展开说明,并结合示例代码演示它们各自的作用范围与使用方式。

一、public:公共访问级别

public关键字是类型和类型成员的访问修饰符,公共访问是允许的最高访问级别,对访问公共成员没有任何限制。有关public与其他访问修饰符的比较,请参见可访问性级别。

在下面的示例中,声明了两个类:MyClass1和MyClass2,并直接从MyClass2访问MyClass1的公共成员x和y。

// protected_public.cs // Public access using System; class MyClass1 { public int x; public int y; } class MyClass2 { public static void Main() { MyClass1 mC = new MyClass1(); // Direct access to public members: mC.x = 10; mC.y = 15; Console.WriteLine("x = {0}, y = {1}", mC.x, mC.y); } }

输出结果:

x = 10, y = 15

如果将public访问级别更改为private或protected,将收到如下错误信息:

'MyClass1.y' is inaccessible due to its protection level.

二、protected:受保护的访问级别

protected关键字是一个成员访问修饰符。从声明受保护成员的类中,以及从声明受保护成员的类派生的任何类中,都可以访问该成员。

需要注意的是:仅当访问通过派生类类型发生时,基类的受保护成员在派生类中才是可访问的。例如,请看以下代码段:

class A { protected int x = 123; } class B : A { void F() { A a = new A(); B b = new B(); a.x = 10; // Error b.x = 10; // OK } }

语句a.x = 10将生成错误,因为A不是从B派生的。

  • 结构成员无法声明为protected,因为结构不支持继承。
  • 对于不是从受保护成员所在类派生的类,引用其中受保护的成员是错误的。
  • 有关受保护成员的更多信息,请参见 3.5.3 实例成员的受保护访问。
  • 有关protected与其他访问修饰符的比较,请参见可访问性级别。

在下面的示例中,类MyDerivedC从MyClass派生,因此可以从该派生类直接访问基类的受保护成员。

// protected_keyword.cs using System; class MyClass { protected int x; protected int y; } class MyDerivedC : MyClass { public static void Main() { MyDerivedC mC = new MyDerivedC(); // Direct access to protected members: mC.x = 10; mC.y = 15; Console.WriteLine("x = {0}, y = {1}", mC.x, mC.y); } }

输出结果:

x = 10, y = 15

如果将x和y的访问级别更改为private,编译器将发出错误信息:

'MyClass.y' is inaccessible due to its protection level. 'MyClass.x' is inaccessible due to its protection level.

三、private:私有访问级别

private关键字是一个访问修饰符,私有访问是允许的最低访问级别。私有成员只有在声明它们的类和结构体中才是可访问的,同一体中的嵌套类型也可以访问那些私有成员。在定义私有成员的类或结构外引用它,会导致编译时错误。

有关private和其他访问修饰符的比较,请参见可访问性级别。

在此例中,Employee类包含一个公共成员name和一个私有成员salary。可以直接访问公共成员,对于私有成员则必须通过公共方法AccessSalary()访问。

// private_keyword.cs using System; class Employee { public string name = "xx"; double salary = 100.00; // private access by default public double AccessSalary() { return salary; } } class MainClass { public static void Main() { Employee e = new Employee(); // Accessing the public field: string n = e.name; // Accessing the private field: double s = e.AccessSalary(); } }

在上面的示例中,如果试图通过如下语句直接访问私有成员:

double s = e.salary;

将收到错误信息:

'Employee.Salary' is inaccessible due to its protection level.

四、综合示例:三种修饰符的对比

下面通过一个完整的示例,对比public、protected和private在不同类中的可访问性差异。

using System; class TestFirst { public string s; // 公有成员 protected int i; // 保护成员 private double d; // 私有成员 public void funFirst() { s = "Welcome 同学们!"; // 正确,允许访问自身成员 i = 100; // 正确,允许访问自身成员 d = 77.77; // 正确,允许访问自身成员 } public static void Main(string[] args) { TestFirst first = new TestFirst(); TestSecond second = new TestSecond(); TestThird third = new TestThird(); first.s = "first 同学们,你好!"; Console.WriteLine("{0}", first.s); second.funSecond(); third.funThird(); } } class TestSecond : TestFirst // 在 C# 中这叫派生 { int x; // 私有成员 public void funSecond() { x = 100; // 正确,允许访问自身成员 s = "second 同学们!"; // 正确,允许访问类 TestFirst 的公有成员 Console.WriteLine("{0}", s); // d = 222.22; // 错误,不能访问类 TestFirst 的私有成员 i = 222; // 正确,允许访问类 TestFirst 的保护成员 } } class TestThird { public void funThird() { TestFirst c = new TestFirst(); // 声明类 TestFirst 的实例 c c.s = "third dongguo!"; // 正确,允许访问类 TestFirst 的公有成员 Console.WriteLine("{0}", c.s); // c.d = 333.333; // 错误,不能访问类 TestFirst 的私有成员 // c.i = 333; // 错误,不能访问类 TestFirst 的保护成员 } }

从示例可以看出:

  • public成员在任何位置都可以访问,包括非派生类TestThird。
  • protected成员只能在派生类TestSecond内部通过派生类实例访问,非派生类TestThird无法访问。
  • private成员只能在声明它的类TestFirst内部访问,派生类和非派生类都无法访问。

五、小结

修饰符访问范围典型使用场景
public任何位置均可访问对外暴露的 API、公共属性与方法
protected声明类及其派生类内部供子类扩展或重写的成员
private仅声明它的类或结构体内部内部实现细节、字段封装

合理选择访问修饰符,既能保证类的封装性,又能为派生类留出必要的扩展空间,是编写高质量 C# 代码的基础。

注:以上部分资源来源于 MSDN。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/27 0:47:18

神经逻辑编程:融合神经网络与符号推理的自动化决策技术

1. 神经逻辑编程与自动化推理的融合趋势去年在调试一个复杂业务规则引擎时,我遇到了传统逻辑编程的典型困境:当需要处理模糊边界条件和动态权重计算时,Prolog的确定性子句逻辑显得力不从心。正是这次经历让我开始关注神经符号系统&#xff08…

作者头像 李华
网站建设 2026/10/27 0:36:31

Claude模型内存管理技术解析

我无法根据当前输入生成符合要求的博文。原因如下:项目标题为"claude-mem",但项目正文、关键词、摘要描述全部为空;所谓“相关热搜词”和“最新网络热词”仅重复了标题本身("claude-mem")&#xf…

作者头像 李华
网站建设 2026/10/27 0:25:50

t3code:基于Electron+CLI的iOS跨平台Web调试工具

1. 项目概述:t3code 是什么?它解决的不是“工具问题”,而是开发者工作流断点t3code 这个名字乍看像某个小众 CLI 工具的代号,但结合当前高频热词——CLI、Electron、web app、iOS——它实际指向一个正在快速成型的、面向全栈与跨端…

作者头像 李华
网站建设 2026/10/27 0:14:33

WorkBuddy+Obsidian:数学讲师的备课出题与公式排版工作流

你有没有经历过这样的夜晚:白天刚讲完一整天的课,晚上还要坐在电脑前,把教材里的公式一个个排队对齐。我做了六年的培训讲师,主要教数学和统计类课程,最怕的不是上课,而是备课和出题。以前一本讲义加一套配…

作者头像 李华
网站建设 2026/10/27 0:12:10

微软Fabric智能体如何学习真实业务运作

1. 项目概述:当业务系统开始“自己学着干活”“微软 Fabric 成为智能体学习业务运作的平台”——这句话乍看像一句宣传口径,但如果你在企业里做过三年以上数据、流程或系统集成相关工作,第一反应大概率是:终于来了。不是又一个“A…

作者头像 李华
网站建设 2026/10/27 0:12:07

从MCP协议到AI Agent:智能系统的演进与实现

1. 从MCP协议到AI Agent:智能演进的技术脉络上世纪60年代诞生的MCP(Master Control Program)协议,最初设计用于协调大型计算机系统中的资源分配与任务调度。这个看似与AI无关的底层协议,实际上奠定了现代智能体系统的两…

作者头像 李华