C# 접근 한정자 완전 이해: public, private, protected, internal 등
C# 접근 한정자 (Access Modifiers) 완전 이해
이 가이드는 C#의 다양한 접근 한정자(public, private, protected, internal, protected internal, private protected)가 타입과 멤버 가시성을 어떻게 제어하는지 실제 코드 예제로 설명합니다.
C#에서 접근 한정자는 필드 읽기/쓰기, 메서드 호출, 타입 인스턴스화 권한을 결정합니다. 예:
class Student {
public string name;
private int num;
}
name은 어디서든 접근 가능, num은 Student 클래스 내부에서만 접근 가능.
접근 한정자 종류
- public
- private
- protected
- internal
- protected internal
- private protected
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) {
Student student1 = new Student();
Console.WriteLine("Name: " + student1.name);
student1.Print();
Console.ReadLine();
}
}
}
출력
Name: Sheeran
Hello from Student class
필드와 메서드 모두 public이므로 Program 클래스에서 자유롭게 접근.
팁: 객체 student1로 Student 멤버 접근. 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) {
Student student1 = new Student();
Console.WriteLine("Name: " + student1.name);
student1.Print();
Console.ReadLine();
}
}
}
name이나 Print를 Program에서 접근 시도 시:
CS0122 'Student.name' is inaccessible due to its protection level
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 : Student {
static void Main(string[] args) {
Program program = new Program();
Console.WriteLine("Name: " + program.name);
Console.ReadLine();
}
}
}
출력
Name: Sheeran
Program이 Student 상속받아 protected name 필드 접근 가능.
4. Internal 접근 한정자
internal 멤버는 동일 어셈블리(컴파일된 코드 논리 단위) 내부에서만 가시적. 어셈블리는 프로젝트 빌드 시 컴파일러가 생성.
단일 어셈블리 내부:
using System;
namespace Assembly {
class Student {
internal string name = "Sheeran";
}
class Program {
static void Main(string[] args) {
Student theStudent = new Student();
Console.WriteLine("Name: " + theStudent.name);
Console.ReadLine();
}
}
}
출력
Name: Sheeran
같은 어셈블리 내에서는 public처럼 동작.
다른 어셈블리에서는 접근 불가:
// Assembly1
using System;
namespace Assembly1 {
public class StudentName {
internal string name = "Sheeran";
}
}
// Assembly2
using System;
using Assembly1;
namespace Assembly2 {
class Program {
static void Main(string[] args) {
StudentName student = new StudentName();
Console.Write(student.name); // CS0122
Console.ReadLine();
}
}
}
Assembly2 컴파일 시도 시:
CS0122 'StudentName.name' is inaccessible due to its protection level
5. Protected Internal 접근 한정자
protected internal 조합은 동일 어셈블리 내부 또는 다른 어셈블리의 파생 타입에서 접근 허용.
// Assembly1
using System;
namespace Assembly1 {
public class Greet {
protected internal string msg = "Hello";
}
}
// Assembly2
using System;
using Assembly1;
namespace Assembly2 {
class Program : Greet {
static void Main(string[] args) {
Program greet = new Program();
Console.Write(greet.msg);
Console.ReadLine();
}
}
}
출력
Hello
6. Private Protected 접근 한정자
C# 7.2 도입. private protected는 선언 클래스와 동일 어셈블리 내 파생 클래스로 가시성 제한.
// Assembly1
using System;
namespace Assembly1 {
public class StudentName {
private protected string name = "Sheeran";
}
class Program1 : StudentName {
static void Main(string[] args) {
Program1 student = new Program1();
Console.Write(student.name);
Console.ReadLine();
}
}
}
// Assembly2
using System;
using Assembly1;
namespace Assembly2 {
class Program : StudentName {
static void Main(string[] args) {
Program student = new Program();
Console.Write(student.name); // CS0122
Console.ReadLine();
}
}
}
Assembly2 접근 실패: 멤버가 어셈블리 밖으로 노출되지 않음, 파생 타입이라도.
참고: 타입(클래스, 인터페이스 등)은 public, internal만 사용 가능. 나머지 한정자는 멤버에만 적용.