본문 바로가기
C#

[C#] 속성(Property)과 접근자(get, set, init), 읽기/쓰기 전용 속성

by RucA 2024. 4. 30.
728x90
반응형

속성은 클래스의 전용 필드 값을 읽거나 쓰고 연산하는 유연한 방법을 제공하는 멤버로, 접근자라는 특수 메서드이다. 주로 private한 필드를 public 속성으로 외부에 공개할 때 사용하며, 안정성과 유연성을 높이는 것에 도움을 준다. 관련한 내용을 정리해보겠다.

 

 

속성 접근자


속성 접근자를 사용해 필드의 값을 가져오고(get) 설정하는(set) 기능을 수행할 수 있다.

 

  • get 접근자 (게터 : getter) : 특정 값 또는 특정 필드 값을 반환
  • set 접근자 (세터 : setter) : value 키워드를 사용해 값을 읽어 관련 필드에 저장
  • init 접근자 : set 접근자와 거의 같으나, 생성자나 개체 이니셜라이저에 의해서만 사용 가능
using System;

class PropertyPractice
{
    //private 필드
    private string hello;

    //private 필드 값을 외부에 공개하는 속성
    public string Hello
    {
        //get 접근자
        get { return hello; }
        
        //set 접근자 : value 키워드 사용
        set { hello = value; }
    }
    
    static void Main()
    {
        var greeting = new PropertyPractice();
        
        //greeting.hello로는 읽기 및 쓰기 불가능(private이므로)
        greeting.Hello = "안녕하세요";		//set
        Console.WriteLine(greeting.Hello);	//get
    }
}

 

 

전체 속성과 자동 구현 속성(자동 속성)


위의 예제처럼 필드와 속성을 함께 사용하는 것은 전체 속성으로 원래 기본값이었으나, 자동 구현 속성이 나온 이후에는 별도의 추가적인 연산이 필요한 것이 아니면 이를 주로 사용한다. 전체 속성을 쓰기 편하게 줄여 놓은 속성으로, 자동으로 구현된 속성이라고 한다.

 

  • 전체 속성 : 속성에 연결할 필드, get 및 set 접근자 관련 코드를 명시적으로 구현
  • 자동 구현 속성(자동 속성) : 전체 속성을 간소화한 코드로, 구현을 명시적으로 제공하지 않아도 C# 컴파일러가 지원
using System;

class PropertyPractice
{
    //전체 속성
    private string hello1;
    public string Hello1
    {
        get { return hello1; }
        set { hello1 = value; }
    }
    
    //자동 구현 속성
    public string Hello2 { get; set; }
    
    static void Main()
    {
        var greeting = new PropertyPractice();
        
        //전체 속성
        greeting.Hello1 = "안녕하세요1";		//set
        Console.WriteLine(greeting.Hello1);	//get
        
        //자동 구현 속성
        greeting.Hello2 = "안녕하세요2";		//set
        Console.WriteLine(greeting.Hello2);	//get
    }
}

 

  • 자동 속성 이니셜라이져 : 속성을 선언과 동시에 기본값으로 초기화
using System;

class PropertyPractice
{
    //자동 속성 이니셜라이저
    public string Hello { get; set; } = "안녕하세요";
    
    static void Main()
    {
        var greeting = new PropertyPractice();
        Console.WriteLine(greeting.Hello);
    }
}

 

 

읽기 전용 속성과 쓰기 전용 속성


접근자 중 하나만을 사용하는 것으로 읽기/쓰기 전용 속성을 구현할 수 있다. 또는 특정 접근자에 private 또는 protected을 앞에 붙이는 방법으로도 구현할 수 있다.

 

  • 읽기 전용 속성 : set 접근자가 없거나 private 등의 접근 제한자가 있음, set 접근자 대신 init 접근자 사용
  • 쓰기 전용 속성 : get 접근자가 없거나 private 등의 접근 제한자가 있음
using System;

class PropertyPractice
{
    public string RO1 { get; } = "Read-Only";
    public string RO2 { get; private set; } = "Read-Only";
    public string RO3 { get; init; } = "Read-Only";

    private string wo1;
    public string WO1
    {
        set { wo1 = value; }
    }
    
    public string WO2 { set; private get; } = "Read-Only";
    
    static void Main()
    {
        PropertyPractice p = new PropertyPractice();
        Console.WriteLine(p.RO1);
        Console.WriteLine(p.RO2);
        Console.WriteLine(p.RO3);
        p.WO1 = "Write-Only";
        p.WO2 = "Write-Only";
    }
}

 

단 private와 같은 접근 제한자를 활용한 경우, 권한에 따라 get, set이 가능할 수 있다. 유연하게 권한에 따라 부여해야 할 경우 접근 제한자를, 원천 봉쇄하고자 하는 경우 아예 접근자를 쓰지 않는 것을 추천한다. 추가적으로 이 예제를 만들면서 알게 된 사실인데, 자동 구현 속성의 경우 set 접근자만 있는 경우는 지원을 안하는 듯 하다.

 

 

식 본문 속성(expression bodied property)


식 본문 속성은 => 연산자를 활용해 속성을 축약해 표현하는 것으로, 값을 그대로 할당 및 가져오기보다는 특정한 연산을 해서 값을 할당하거나 가져올 때 사용한다.

 

  • 식 본문 속성의 활용
using System;

class PropertyPractice
{
    public string Name { get; set; }
    public DateTime EnterDate { get; set; } = DateTime.Today;
    
    //식 본문 속성
    public DateTime GraduateDate { get => (EnterDate.AddYears(4)); }
    
    static void Main()
    {
        PropertyPractice p = new PropertyPractice();
        p.Name = "김밥";
        p.EnterDate = new DateTime(2000, 02, 23);
        Console.WriteLine($"{p.Name}님의 졸업일 : {p.GraduateDate}");
    }
}

 

이 포스팅에서는 속성에 관련한 기본적인 내용과 코드를 더 간소하게 치는 것을 중점으로 다루었다. 속성에 관련한 몇 가지 재미있는 내용을 다음 포스팅에 이어서 올릴 예정이다.

728x90
반응형