C#

[Unity] 액세스 한정자 ( public, protected, internal, private )

EveryDay.DevUp 2021. 12. 27. 21:16

액세스 한정자는 멤버 또는 형식의 선언된 접근성을 지정하는데 사용되는 키워드

키워드 접근성
public 제한 없음
protected 포함 및 파생
internal 동일 어셈블리로 제한
protected internal 동일 어셈블리 또는 다른 어셈블리여도 포함하는 클래스에서 파생된 형식
private 포함
private protected 포함 or 동일 어셈블리 내의 포함하는 클래스의 파생 ( C# 7.2 이상 )

* 네임 스페이스에는 액세스 한정자가 허용되지 않음 

public class A { }
// 동일 어셈블리에서는 internal만 사용할 경우 public과 접근 제어 수준이 동일함
internal class B { } 

// protected, protected internal, private, private protected는 namespace에는 허용되지 않기 때문에 에러
protected class C { }

* 멤버 선언이 발생한 구문에 따라 특정 액세스 한정자만 허용

- 멤버가 다른 형식 내에 중첩되면 해당 엑세스 가능 영역은 엑세스 가능성 수준 및 한 수준 위 형식의 엑세스 가능 영역에 의해 결정됨

public class A
{
	private class AA
    {
		public int x;
    }
}

public class B 
{
	void Test()
    {
        // AA Class가 private 이기 때문에 AA.x가 public 이여도 외부에서 접근할 수 없음
        A.AA aa = new A.AA();
    }
}

* 기본 멤버 액세스 가능성 및 멤버의 허용된 액세스 가능성

구문 기본 멤버 엑세스 멤버의 허용된 액세스
enum public none
class  private  public / protected / internal / private / protected internal, private protected
interface public public / protected / internal / *private ( 기본 구현 필요 ) / protected internal, private protected
struct private 상속이 안되기 때문에 protected는 제외됨

public / internal / private 

* protected

class A
{
    protected int x = 1;
}

class B : A
{
    void Start()
    {
        A a = new A();
        B b = new B();

        // x에 접근할 수 없기 때문에 에러
        a.x = 1;

        // x에 접근할 수 있기 때문에 정상
        x = 2;
    }
}

* internal

// EveryDayDevup-Framework 어셈블리
// 같은 어셈블리에서는 접근이 가능
internal class A
{
	public static int x = 1;
}

class C
{
	void Test()
    {
		A.x = 2;
    }
}


// Assembly-CSharp
class B 
{
    void Start()
    {
    	// 어셈블리가 다르기 때문에 A에 접근할 수 없음 
        A.x = 3;
    }
}
// internal class를 public으로 변경하고 멤버를 internal로 변경
public class A
{
	internal static int x = 1;
}

class C
{
	void Test()
    {
		A.x = 2;
    }
}


class B : 
{
    void Start()
    {
        A a = new A();
    	// 인스턴스 생성은 가능하지만
        // internal로 설정한 x에 접근할 수 없음 
        a.x = 2;
    }
 }

* protected internal

// EveryDayDevup-Framework
// 같은 어셈블리에 있는 C는 A.x의 접근할 수 있음
public class A
{
	internal int x = 1;
}

public class C 
{
	void Test()
    {
		x = 3;
    }
}

// Assembly-CSharp
// 다른 어셈블리에 있는 B클래스는 상속을 해도 A.x의 접근할 수 없음
class B : A
{
    void Start()
    {
        x = 2;
    }
}
// EveryDayDevup-Framework
// protected internal을 사용하면 다른 어셈블리의 파생 클래스에서 x의 접근이 가능
// protected internal은 멤버에만 사용할 수 있음
public class A
{
	protected internal int x = 1;
}

// Assembly-CSharp
class B : A
{
    void Start()
    {
     	// protected internal은 상속 시 다른 어셈블리에서 접근이 가능
        x = 2;
    }
}

* private

class A
{
    private int x;
    
    public int GetX() {
    	return x;
    }
}

class B
{
    void Test()
    {
        A a = new A();
        // private는 선언된 클래스 또는 구조체의 본문에서만 접근 가능
        // a.x의 접근할 수 없기 때문에 에러
        a.x;
        
        // A에서 x를 접근할 수 있도록 해줘야함
        a.GetX();
    }
}

* private protected

// EveryDayDevup-Framework
// 동일 어셈블리의 파생 클래스에서는 접근이 가능
public class A
{
	private protected int x = 1;
}

public class C : A
{
	void Test()
    {
		x = 2;
    }
}

// Assembly-CSharp
class B : A
{
    void Test()
    {
    	// 다른 어셈블리에서는 상속을 받아도 x에 접근할 수 없음 
        x = 3;
    }
}

*출처 및 참고 블로그

https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/access-modifiers

 

액세스 한정자 - C# 참조

액세스 한정자(C# 참조) 이 문서의 내용 --> 액세스 한정자는 멤버 또는 형식의 선언된 접근성을 지정하는 데 사용되는 키워드입니다. 이 섹션에서는 다음 네 가지 액세스 한정자를 소개합니다. pu

docs.microsoft.com