在 C# 中,访问修饰符指定类型(类、接口等)和类型成员(字段、方法等)的可访问性。例如,
class Student {
public string name;
private int num;
}
这里,
- name - public 字段,可以从任何地方访问
- num - private 字段,只能在 Student 类内访问
访问修饰符的类型
在 C# 中,有 4 种基本类型的访问修饰符。
- public
- private
- protected
- internal
1. public 访问修饰符
当我们声明一个类型或类型成员为 public
时,它可以从任何地方访问。例如,
using System;
namespace MyApplication {
class Student {
public string name = "Sheeran";
public void print() {
Console.WriteLine("Hello from Student class");
}
}
class Program {
static void Main(string[] args) {
// creating object of Student class
Student student1 = new Student();
// accessing name field and printing it
Console.WriteLine("Name: " + student1.name);
// accessing print method from Student
student1.print();
Console.ReadLine();
}
}
}
输出
Name: Sheeran Hello from Student class
在上面的示例中,我们创建了一个名为 Student 的类,其中包含一个字段 name 和一个方法 print()。
// accessing name field and printing it
Console.WriteLine("Name: " + student1.name);
// accessing print method from Student
student1.print();
由于字段和方法都是 public 的,我们可以在 Program 类中访问它们。
注意:我们使用了 Student 类的对象 student1 来访问其成员。要了解更多信息,请访问C# 类和对象。
2. private 访问修饰符
当我们使用 private
访问修饰符声明一个类型成员时,它只能在同一个 class
或 struct
内访问。例如,
using System;
namespace MyApplication {
class Student {
private string name = "Sheeran";
private void print() {
Console.WriteLine("Hello from Student class");
}
}
class Program {
static void Main(string[] args) {
// creating object of Student class
Student student1 = new Student();
// accessing name field and printing it
Console.WriteLine("Name: " + student1.name);
// accessing print method from Student
student1.print();
Console.ReadLine();
}
}
}
在上面的示例中,我们创建了一个名为 Student 的类,其中包含一个字段 name 和一个方法 print()。
// accessing name field and printing it
Console.WriteLine("Name: " + student1.name);
// accessing print method from Student
student1.print();
由于字段和方法都是 private 的,我们无法在 Program 类中访问它们。此处,代码将生成以下错误。
Error CS0122 'Student.name' is inaccessible due to its protection level
Error CS0122 'Student.print()' is inaccessible due to its protection level
3. protected 访问修饰符
当我们声明一个类型成员为 protected
时,它只能在同一类及其派生类中访问。例如,
using System;
namespace MyApplication {
class Student {
protected string name = "Sheeran";
}
class Program {
static void Main(string[] args) {
// creating object of student class
Student student1 = new Student();
// accessing name field and printing it
Console.WriteLine("Name: " + student1.name);
Console.ReadLine();
}
}
}
在上面的示例中,我们创建了一个名为 Student 的类,其中包含一个字段 name。由于该字段是 protected 的,我们无法在 Program 类中访问它。
此处,代码将生成以下错误。
Error CS0122 'Student.name' is inaccessible due to its protection level
现在,让我们尝试从派生类访问 protected
成员。
using System;
namespace MyApplication {
class Student {
protected string name = "Sheeran";
}
// derived class
class Program : Student {
static void Main(string[] args) {
// creating object of derived class
Program program = new Program();
// accessing name field and printing it
Console.WriteLine("Name: " + program.name);
Console.ReadLine();
}
}
}
输出
Name: Sheeran
在上面的示例中,我们创建了一个名为 Student 的类,其中包含一个 protected 字段 name。请注意,我们已将 Program 类继承自 Student 类。
// accessing name field and printing it
Console.WriteLine("Name: " + program.name);
由于 protected
成员可以从派生类访问,因此我们可以从 Program 类访问 name。
4. internal 访问修饰符
当我们声明一个类型或类型成员为 internal
时,它只能在同一个程序集中访问。
程序集是类型(类、接口等)和资源(数据)的集合。它们被构建为协同工作并形成功能的逻辑单元。
因此,当我们运行一个程序集时,程序集内的所有类和接口都会一起运行。要了解更多信息,请访问C# 程序集。
示例:同一个程序集内的 internal
using System;
namespace Assembly {
class Student {
internal string name = "Sheeran";
}
class Program {
static void Main(string[] args) {
// creating object of Student class
Student theStudent = new Student();
// accessing name field and printing it
Console.WriteLine("Name: " + theStudent.name);
Console.ReadLine();
}
}
}
输出
Name: Sheeran
在上面的示例中,我们创建了一个名为 Student 的类,其中包含一个字段 name。由于该字段是 internal
的,我们可以在 Program 类中访问它,因为它们在同一个程序集中。
如果我们使用单个程序集中的 internal
,它的作用与 public
访问修饰符相同。
示例:不同程序集中的 internal
我们先创建一个程序集。
// Code on Assembly1
using System;
namespace Assembly1 {
public class StudentName {
internal string name = "Sheeran";
}
class Program {
static void Main(string[] args) {
}
}
}
这里,这段代码在程序集1中。我们在 StudentName 类中创建了一个 internal 字段 name。现在,此字段只能从同一个程序集程序集1访问。
现在,我们创建另一个程序集。
// Code on Assembly2
using System;
// access Assembly1
using Assembly1;
namespace Assembly2 {
class Program {
static void Main(string[] args) {
StudentName student = new StudentName();
// accessing name field from Assembly1
Console.Write(student.name);
Console.ReadLine();
}
}
}
这里,这段代码在程序集2中。我们正在尝试访问 StudentName 类(程序集1)的 name 字段。
要访问程序集1中的字段,我们首先需要将程序集1的引用设置为程序集2。现在代码
using Assembly1;
允许我们将程序集1中的代码用于程序集2。
这里,当我们尝试从程序集2访问 name 字段时,我们会收到一个错误。
Error CS0122 'StudentName.name' is inaccessible due to its protection level
这是因为 name 是一个 internal 字段,存在于程序集1中。
5. protected internal 访问修饰符
protected internal
是 protected
和 internal
访问修饰符的组合。
当我们声明一个成员为 protected internal
时,它可以在同一程序集和包含类的派生类(来自任何其他程序集)中访问。
// Code on Assembly1
using System;
namespace Assembly1 {
public class Greet {
protected internal string msg="Hello";
}
class Program {
static void Main(string[] args) {
Greet greet = new Greet();
Console.WriteLine(greet.msg);
Console.ReadLine();
}
}
}
输出
Hello
上面的代码在程序集1中。
在上面的示例中,我们创建了一个名为 Greet 的类,其中包含一个字段 msg。由于该字段是 protected internal 的,我们可以在 Program 类中访问它,因为它们在同一个程序集中。
让我们从另一个程序集派生一个类,继承自 Greet,然后尝试从它访问 protected internal 字段 msg。
// Code on Assembly2
using System;
// access Assembly1
using Assembly1;
namespace Assembly2 {
// derived class of Greet
class Program: Greet {
static void Main(string[] args) {
Program greet = new Program();
// accessing name field from Assembly1
Console.Write(greet.msg);
Console.ReadLine();
}
}
}
输出
Hello
上面的代码在程序集2中。
在上面的示例中,我们继承了程序集1中的 Greet 类的 Program 类。
// accessing name field from Assembly1
Console.Write(greet.msg);
我们可以从程序集2访问程序集1的 Greet 类的 msg 字段。
这是因为 msg 是一个 protected internal 字段,并且我们尝试从 Greet 的子类中访问它。
6. private protected 访问修饰符
private protected
访问修饰符是 private
和 protected
的组合。它从 C# 7.2 及更高版本可用。
当我们声明一个成员为 private protected
时,它只能在同一类及其派生类(位于同一个程序集中)中访问。例如,
// Code in Assembly1
using System;
namespace Assembly1 {
public class StudentName {
private protected string name = "Sheeran";
}
//derived class of StudentName class
class Program1 : StudentName {
static void Main(string[] args) {
Program1 student = new Program1();
// accessing name field from base class
Console.Write(student.name);
Console.ReadLine();
}
}
}
输出
Sheeran
上面的代码在程序集1中
在上面的示例中,我们创建了一个名为 StudentName 的类,其中包含一个 private protected
字段 name。
请注意,我们已将 Program1 类继承自 StudentName 类。
由于 private protected
成员可以从同一个程序集中的派生类访问,因此我们可以从 Program1 类访问 name。
让我们从另一个程序集派生一个类,继承自 StudentName,然后尝试从它访问 private protected 字段 name。例如,
// Code in Assembly2
using System;
//access Assembly1
using Assembly1;
namespace Assembly2 {
//derived class of StudentName
class Program : StudentName {
static void Main(string[] args) {
Program student = new Program();
// accessing name field from Assembly1
Console.Write(student.name);
Console.ReadLine();
}
}
}
上面的代码在程序集2中
在上面的示例中,当我们尝试从 StudentName 的派生类访问 name 字段时,我们会收到一个错误。
Error CS0122 'StudentName.name' is inaccessible due to its protection level
这是因为 name 字段在程序集1中,而派生类在程序集2中。
注意:我们也可以将访问修饰符与类型(类、接口等)一起使用。但是,我们只能使用 public 和 internal 访问修饰符的类型。