首页 > 后端开发 > C#.Net教程 > C# 中的访问修饰符

C# 中的访问修饰符

WBOY
发布: 2024-09-03 15:24:47
原创
752 人浏览过

本文从 C# 编程语言的角度涵盖了面向对象编程的最基本概念。这个概念被称为——访问修饰符。要回答的第一个问题是 – 什么是访问修饰符?简而言之,访问修饰符控制可以在代码的哪一部分访问哪些对象/变量/常量/方法(实际上是所有内容)。访问修饰符在证明面向对象编程中的抽象概念方面发挥着重要作用。它们控制程序的哪些部分应该对最终用户可见,哪些部分不应该对最终用户可见。当然,最终用户最不关心算法中涉及的常量和变量。他只关心需要调用什么方法来获取输出。

C# 中的访问修饰符类型

C#为我们提供了四种类型的访问修饰符:

  • 私有(默认访问修饰符,枚举和接口除外)
  • 受保护(略有限制)
  • 公共(无限制,枚举和接口的默认选择)
  • 内部(同一程序集中公开)

除了这四种访问修饰符之外,还有两种访问级别组合 -

  • 受保护的内部
  • 私人保护

让我们通过一个例子来理解每一个。

1.私人

私人是最受限制的访问级别。它也是所有常量、变量、用户定义对象等的默认访问修饰符。默认情况下,只有枚举和接口是公共的。因此,如果您没有指定任何访问修饰符,C# 会为其分配默认修饰符。

私有对象在类或结构体或声明它们的程序部分之外不可访问。任何尝试访问声明对象的主体范围之外的对象都会导致编译时错误。

示例#1

using System;
class Employee //private by default
{
string name; //private by default
public string GetName()
{
return name;
}
public void SetName(string name)
{
this.name = name;
}
}
public class Program
{
public static void Main()
{
Employee emp = new Employee();
emp.SetName("John");
Console.Write("Employee name is " + emp.GetName());
// compile time error - 'Employee.name' is inaccessible due to its protection level
// Console.Write("Employee name is " + emp.name);
}
}
登录后复制

输出:

C# 中的访问修饰符

示例 #2

using System;
public class Program
{
public static void Main()
{
int x = 5; //private to the Main method, accessible inside nested code blocks in the Main method
if (true)
{
int y = 10; //private to the if block, not accessible outside if block
Console.WriteLine("x = " + x);
Console.WriteLine("y = " + y);
}
Console.WriteLine("x = " + x);
// compile-time error - The name 'y' does not exist in the current context.
// Console.WriteLine("y = " + y);
}
}
登录后复制

输出:

C# 中的访问修饰符

2.受保护

受保护的访问说明符限制对象只能从类的派生实例访问。因此,如果子类对象尝试访问父类的受保护对象,则这是允许的。非派生类不能访问任何类的受保护成员。当然,受保护的对象可以通过其自己类的方法访问。

示例:

using System;
class Parent
{
protected string x;
public Parent()
{
x = "abc"; //accessible to own class methods
}
}
class Child : Parent // derived class
{
public static void Main()
{
var parentObj = new Parent();
var childObj = new Child();
Console.WriteLine(childObj.x); //accessible to derived class object instances
// compile-time error - Cannot access protected member 'Parent.x' via a qualifier of type 'Parent'; the qualifier must be of type 'Child' (or derived from it)
// Console.WriteLine(parentObj.x);
}
}
登录后复制

输出:

C# 中的访问修饰符

3.公众

这是受限制最少的访问修饰符。公共对象实际上可供整个外部世界访问,从而使它们成为允许的最高访问修饰符。当然,这需要付出沉重的代价——最少保护的代价。

代码的任何部分都可以访问公共成员。这使得它们最不安全。任何代码逻辑都可以修改它们的值,这可能会导致意外的行为。因此,在公开任何对象之前必须非常谨慎。

在我们在私有访问修饰符示例中创建的同一个 Employee 类中,如果我们更改公共的访问级别,则不需要任何 Getter 和 Setter 方法。事实上,最佳实践是将对象设为私有并使用 C# Getter 和 Setter 属性。

示例:

using System;
class Employee
{
public string name;
}
public class Program
{
public static void Main()
{
Employee emp = new Employee();
emp.name = "John";
Console.Write("Employee name is " + emp.name);
}
}
登录后复制

输出:

C# 中的访问修饰符

4.内部

内部对象和方法只能在同一程序集中访问。当您想要将任何对象公开,但又希望将其访问限制为仅对您正在编码的框架进行访问时,这是一个非常有用的访问修饰符。

因此,本质上,同一程序集的所有区域都可以访问所有内部对象。

让我们创建两个控制台应用程序来了解此工作原理。

示例:

第 1 步:创建一个 C# 控制台应用程序并将以下代码放入其中:

using System;
namespace ConsoleApp1
{
public class Parent
{
internal int x;
public Parent()
{
x = 10;
}
}
public class Program
{
public static void Main()
{
var parentObj = new Parent();
// accessible within the same assembly
Console.Write("The value of x = " + parentObj.x);
}
}
}
登录后复制

第 2 步:构建解决方案以从 bin 文件夹获取 .dll 文件。

C# 中的访问修饰符

第 3 步:创建另一个控制台应用程序并引用 ConsoleApp1 中的程序集文件。单击下图中的“添加引用”,然后浏览到步骤 2 中的 .dll 文件的位置。它必须类似于 ~/ConsoleApp1/bin/Debug/ConsoleApp1.dll。

C# 中的访问修饰符

添加 .dll 文件后,您应该在程序集下找到它。

C# 中的访问修饰符

Step4: Place the below code in ConsoleApp2.

using System;
using ConsoleApp1; //referencing the first assembly
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
var parentObj = new Parent();
//not accessible outside the assembly
Console.Write(parentObj.x);
}
}
}
登录后复制

Step5: When you build ConsoleApp2, you will get a compile-time error indicating that ‘x’ from ConsoleApp1 cannot be accessed in other assemblies due to its protection level.

C# 中的访问修饰符

5. Protected Internal

This is a combination of both Protected and Internal access modifiers. An important concept to understand here is that Protected Internal means Protected OR Internal. It is a union of both access modifiers. It must never be thought to be an intersection.

So, Internal objects are not accessible outside the assembly, while Protected objects are accessible to any derived class in any assembly. What if I want to protect my object only in other assemblies and not in the same assembly? Simple solution – declare it as protected internal.

Example:

Step 1: Let us modify our ConsoleApp1 to reflect the code below. Notice we have changed the access level of our variable ‘x’ to protected internal.

using System;
namespace ConsoleApp1
{
public class Parent
{
protected internal int x;
public Parent()
{
x = 10;
}
}
public class Program
{
public static void Main()
{
var parentObj = new Parent();
// accessible within the same assembly
Console.Write("The value of x = " + parentObj.x);
}
}
}
登录后复制

Step 2: Build the solution again and replace the .dll in ConsoleApp2 with the updated one.

Step 3: Update the code in ConsoleApp2 as below:

using System;
using ConsoleApp1; //referencing the first assembly
namespace ConsoleApp2
{
class Program: Parent
{
static void Main(string[] args)
{
var progObj = new Program();
//accessible only via an object of the derived class.
Console.Write(progObj.x);
Console.Read();
}
}
}
登录后复制

Step 4: Run ConsoleApp2 to see the output.

C# 中的访问修饰符

6. Private Protected

This is a union combination of both Private and Protected access modifiers. Protected Internal means Protected OR Internal. So, Private objects are not accessible outside the code block in which it is declared, while Protected objects are accessible to any derived class in any assembly. What if I want to restrict my object’s access even in derived classes in other assemblies? Simple solution – declare it as protected internal.

Example:

Let us modify the access level of ‘x’ in ConsoleApp1 to Private Protected.

using System;
namespace ConsoleApp1
{
public class Parent
{
private protected int x;
public Parent()
{
x = 10;
}
}
public class Child: Parent {
public void DisplayX() {
// accessible only via derived class objects
Console.Write("Value of x = " + x);
}
}
public class Program
{
public static void Main()
{
var childObj = new Child();
childObj.DisplayX();
Console.Read();
}
}
}
登录后复制

Output:

C# 中的访问修饰符

Tabular Comparison

Following is a tabular comparison of Access Modifiers in C#:

Access Specifier Same Assembly Other Assembly
Same Class Derived Class Non-Derived Class Derived Class Non-Derived Class
Private Yes No No No No
Public Yes Yes Yes Yes Yes
Protected Yes Yes No Yes No
Internal Yes Yes Yes No No
Protected Internal Yes Yes Yes Yes No
Private Protected Yes Yes No No No

Conclusion

We have seen in the above article that access modifiers control the access of everything in the project. Various combinations of access levels cover the needs of various kinds of accessibility. The developers must choose wisely, keeping in mind the security and the absolute necessity of the object to be accessible in a certain block of code.

以上是C# 中的访问修饰符的详细内容。更多信息请关注PHP中文网其他相关文章!

相关标签:
来源:php
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板