다음을 통해 공유


접근자 액세스 가능성 제한(C# 프로그래밍 가이드)

속성 또는 인덱서의 getset 부분을 접근자라고 합니다. 기본적으로 이러한 접근자는 속하는 속성 또는 인덱서와 동일한 표시 유형 또는 액세스 수준을 갖습니다. 자세한 내용은 접근성 수준을 참조하세요. 그러나 이러한 접근자 중 하나에 대한 액세스를 제한하는 것이 유용한 경우도 있습니다. 일반적으로 get 접근자의 공용 액세스를 유지하면서 set 접근자의 접근성을 제한합니다. 예시:

private string _name = "Hello";

public string Name
{
    get
    {
        return _name;
    }
    protected set
    {
        _name = value;
    }
}

이 예제에서는 Name 속성이 getset 접근자를 정의합니다. get 접근자는 속성 자체의 접근성 수준(이 경우 public)을 받는 반면, set 접근자는 접근자 자체에 protected 액세스 한정자를 적용하여 명시적으로 제한됩니다.

참고 항목

이 문서의 예에서는 자동 구현 속성을 사용하지 않습니다. 자동 구현 속성은 사용자 지정 지원 필드가 필요하지 않은 경우 속성 선언을 위한 간결한 구문을 제공합니다.

접근자의 액세스 한정자에 대한 제한 사항

속성 또는 인덱서의 접근자 한정자 사용에는 다음과 같은 조건이 적용됩니다.

  • 인터페이스 또는 명시적 interface 멤버 구현에는 접근자 한정자를 사용할 수 없습니다.
  • 속성 또는 인덱서에 setget 접근자가 모두 포함된 경우에만 접근자 한정자를 사용할 수 있습니다. 이 경우 두 접근자 중 하나에서만 한정자가 허용됩니다.
  • 속성 또는 인덱서에 override 한정자가 있는 경우 접근자 한정자가 재정의된 접근자의 한정자와 일치해야 합니다(있는 경우).
  • 접근자의 접근성 수준은 속성 또는 인덱서 자체의 접근성 수준보다 더 제한적이어야 합니다.

재정의 접근자의 액세스 한정자

속성 또는 인덱서를 재정의하는 경우 재정의 코드에서 재정의된 접근자에 액세스할 수 있어야 합니다. 또한 속성/인덱서 및 접근자의 접근성이 재정의된 속성/인덱서 및 해당 접근자와 일치해야 합니다. 예시:

public class Parent
{
    public virtual int TestProperty
    {
        // Notice the accessor accessibility level.
        protected set { }

        // No access modifier is used here.
        get { return 0; }
    }
}
public class Kid : Parent
{
    public override int TestProperty
    {
        // Use the same accessibility level as in the overridden accessor.
        protected set { }

        // Cannot use access modifier here.
        get { return 0; }
    }
}

인터페이스 구현

접근자를 사용하여 인터페이스를 구현하는 경우 접근자에 액세스 한정자가 있을 수 없습니다. 그러나 get 등의 한 접근자를 사용하여 인터페이스를 구현하는 경우 다음 예제와 같이 다른 접근자에 액세스 한정자를 사용할 수 있습니다.

public interface ISomeInterface
{
    int TestProperty
    {
        // No access modifier allowed here
        // because this is an interface.
        get;
    }
}

public class TestClass : ISomeInterface
{
    public int TestProperty
    {
        // Cannot use access modifier here because
        // this is an interface implementation.
        get { return 10; }

        // Interface property does not have set accessor,
        // so access modifier is allowed.
        protected set { }
    }
}

접근자 접근성 도메인

접근자의 액세스 한정자를 사용하는 경우 접근자의 접근성 도메인은 이 한정자에 의해 결정됩니다.

접근자의 액세스 한정자를 사용하지 않은 경우 접근자의 접근성 도메인은 속성 또는 인덱서의 접근성 수준에 의해 결정됩니다.

예시

다음 예제에는 세 가지 클래스 BaseClass, DerivedClass, MainClass가 포함되어 있습니다. BaseClass에는 두 클래스의 NameId인 두 가지 속성이 있습니다. 예제에서는 protected, private 등의 제한적인 액세스 한정자를 사용할 때 DerivedClassId 속성을 BaseClassId 속성으로 숨길 수 있는 방법을 보여 줍니다. 따라서 이 속성에 값을 할당하면 BaseClass 클래스의 속성이 대신 호출됩니다. 액세스 한정자를 public으로 바꾸면 속성에 액세스할 수 있습니다.

또한 이 예에서는 DerivedClass에 있는 Name 속성의 set 접근자에 있는 private 또는 protected와 같은 제한적인 액세스 한정자가 파생 클래스의 접근자에 대한 액세스를 방지한다는 것을 보여 줍니다. 이를 할당하거나 액세스 가능한 경우 동일한 이름의 기본 클래스 속성에 액세스하면 오류가 발생합니다.

public class BaseClass
{
    private string _name = "Name-BaseClass";
    private string _id = "ID-BaseClass";

    public string Name
    {
        get { return _name; }
        set { }
    }

    public string Id
    {
        get { return _id; }
        set { }
    }
}

public class DerivedClass : BaseClass
{
    private string _name = "Name-DerivedClass";
    private string _id = "ID-DerivedClass";

    new public string Name
    {
        get
        {
            return _name;
        }

        // Using "protected" would make the set accessor not accessible.
        set
        {
            _name = value;
        }
    }

    // Using private on the following property hides it in the Main Class.
    // Any assignment to the property will use Id in BaseClass.
    new private string Id
    {
        get
        {
            return _id;
        }
        set
        {
            _id = value;
        }
    }
}

class MainClass
{
    static void Main()
    {
        BaseClass b1 = new BaseClass();
        DerivedClass d1 = new DerivedClass();

        b1.Name = "Mary";
        d1.Name = "John";

        b1.Id = "Mary123";
        d1.Id = "John123";  // The BaseClass.Id property is called.

        System.Console.WriteLine("Base: {0}, {1}", b1.Name, b1.Id);
        System.Console.WriteLine("Derived: {0}, {1}", d1.Name, d1.Id);

        // Keep the console window open in debug mode.
        System.Console.WriteLine("Press any key to exit.");
        System.Console.ReadKey();
    }
}
/* Output:
    Base: Name-BaseClass, ID-BaseClass
    Derived: John, ID-BaseClass
*/

설명

new private string Id 선언을 new public string Id로 바꿀 경우 다음과 같이 출력됩니다.

Name and ID in the base class: Name-BaseClass, ID-BaseClass Name and ID in the derived class: John, John123

참고 항목