ホームページ  >  記事  >  バックエンド開発  >  C# のアクセス修飾子

C# のアクセス修飾子

WBOY
WBOYオリジナル
2024-09-03 15:24:47707ブラウズ

この記事では、C# プログラミング言語の観点からオブジェクト指向プログラミングの最も基本的な概念を説明します。この概念は、アクセス修飾子として知られています。答えるべき最初の質問は、「アクセス修飾子とは何ですか?」です。簡単に言えば、アクセス修飾子は、コードのどの部分でどのオブジェクト/変数/定数/メソッド (実際にはすべて) にアクセスできるかを制御します。アクセス修飾子は、オブジェクト指向プログラミングにおける抽象化の概念を実証する上で重要な役割を果たします。これらは、プログラムのどの部分がエンドユーザーに表示され、どの部分が表示されないようにするかを制御します。もちろん、エンドユーザーは、アルゴリズムに含まれる定数や変数についてはほとんど心配しません。彼が関心を持っているのは、出力を取得するためにどのメソッドを呼び出す必要があるかだけです。

C# のアクセス修飾子の種類

C# では、次の 4 種類のアクセス修飾子が提供されます。

  • プライベート (デフォルトのアクセス修飾子、列挙型とインターフェイスを除く)
  • 保護されています (わずかに制限されています)
  • パブリック (制限なし、列挙型とインターフェイスのデフォルトの選択)
  • 内部 (同じアセンブリ内の公開)

これら 4 つのアクセス修飾子とは別に、アクセス レベルの組み合わせがさらに 2 つあります。

  • 保護された内部
  • プライベート保護

例を挙げてそれぞれを理解しましょう。

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.保護されています

Protected アクセス指定子は、クラスの派生インスタンスからのみオブジェクトにアクセスできるように制限します。したがって、子クラスのオブジェクトが親クラスの保護されたオブジェクトにアクセスしようとしても、それは許可されます。非派生クラスは、どのクラスの保護されたメンバーにもアクセスできません。もちろん、保護されたオブジェクトは、独自のクラスのメソッドからアクセスできます。

例:

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.内部

内部オブジェクトとメソッドは、同じアセンブリ内でのみアクセスできます。これは、オブジェクトを公開したいが、そのアクセスをコーディング中のフレームワークにのみ制限したい場合に、非常に便利なアクセス修飾子です。

したがって、本質的に、すべての内部オブジェクトは、同じアセンブリのすべての領域からアクセスできます。

この動作を理解するために 2 つのコンソール アプリケーションを作成してみましょう。

例:

ステップ 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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
前の記事:C# の抽象クラス次の記事:C# の抽象クラス