C#

[C#] 프로퍼티

Prooni 2024. 10. 6. 18:19

안녕하세요!

오늘은 C#의 프로퍼티를 공부해요~

 

먼저 프로퍼티가 왜 나왔는지 볼게요!

프로퍼티는 은닉성편의성을 모두 잡기위해 나왔답니다.

 

클래스에 private으로 선언된 필드의 경우에는

다른 클래스에서 접근하기위해서 Get, Set 메소드를 구현해줘야해요!

 

하지만 편의성을 보면 "=" 연산자를 이용하는 것이 훨씬 좋아보이죠

그래서 이때 프로퍼티를 사용하면 된답니다!

 

아래 코드는 프로퍼티를 사용하지 않고 필드 선언 후

해당 필드에 대한 get, set 메소드를 구현한 코드에요~

class BirthdayInfo
{
    private string name;
    private DateTime birthday;

    public string Name
    {
        get
        {
            return name;
        }
        set
        {
            name = value;
        }
    }

    public DateTime Birthday
    {
        get
        {
            return birthday;
        }
        set
        {
            birthday = value;
        }
    }

    public int Age
    {
        get
        {
            return new DateTime(DateTime.Now.Subtract(birthday).Ticks).Year;
        }
    }
}

 

자 위의 코드를 프로퍼티를 이용해서 고쳐볼게요!

class BirthdayInfo
{
    public string Name { get; set; } = "Unknown";
    public DateTime Birthday { get; set; } = new DateTime(1, 1, 1);
    public int Age
    {
        get
        {
            return new DateTime(DateTime.Now.Subtract(Birthday).Ticks).Year;
        }
    }
}

짠! 훨씬 코드가 간결해졌죠!!

 

이렇게 하면 편의성이 훨씬 높아져요

프로퍼티를 사용하면 편의성뿐만아니라 은닉성도 보장이 되는데요!

 

위 코드처럼 get과 set을 구현하지 않고 키워드만 적으면

자동 구현 프로퍼티가 되어요

따라서 C# 컴파일러에서는 "Name" 프로퍼티에 대해

private으로 필드를 자동으로 선언해준답니다!

 

 

프로퍼티를 통해서 객체를 초기화할 수도 있어요!

아래 코드에 주석으로 객체 초기화 부분을 설명할게요~

namespace ConstructorWithProperty
{
    class BirthdayInfo
    {
        public string Name
        {
            get;
            set;
        }

        public DateTime Birthday
        {
            get;
            set;
        }

        public int Age
        {
            get
            {
                return new DateTime(DateTime.Now.Subtract(Birthday).Ticks).Year;
            }
        }
    }

    class MainApp
    {
        static void Main(string[] args)
        {
        	//이렇게 객체 생성시 프로퍼티를 초기화할 수 있답니다!
            BirthdayInfo birth = new BirthdayInfo()
            {
                Name = "서현",
                Birthday = new DateTime(1991, 6, 28)
            };

            Console.WriteLine($"Name : {birth.Name}");
            Console.WriteLine($"Birthday : {birth.Birthday}");
            Console.WriteLine($"Age : {birth.Age}");
        }
    }
}

 

그리고 프로퍼티를 사용할 때 알아두면 좋은 키워드들이 있어요!

바로 init, required, with 입니다.

 

먼저 init 키워드를 설명드릴게요

프로퍼티를 선언할때 get; set;을 많이 쓰죠?

그런데 한번 설정되고 나서 절대 변하면 안되는 데이터가 있을 수 있어요

이때 set 대신 init 키워드를 사용하면 된답니다!

 

아래 코드처럼 init 키워드를 사용하면

초기화시에만 값을 설정할 수 있고 그 이후에는 값 변경이 불가능해요!

class Transaction
{
    public string From { get; init; }
    public string To { get; init; }
    public int Amount { get; init; }

    public override string ToString()
    {
        return $"{From,-10} -> {To,-10} : {Amount}";
    }
}

 

 

다음은 required 키워드를 알아볼게요

프로퍼티 선언시 한정자 뒤에 required 키워드를 붙여주면

객체 생성시 반드시 해당 프로퍼티를 초기화 하도록 강요할 수 있어요!

아래 코드에서 BirthdayInfo의 프로퍼티 Name, Birthday에 required 키워드가 있으므로

이제 BirthdayInfo의 인스턴스를 생성할때 꼭 Name, Birthday를 초기화해야해요~

class BirthdayInfo
{
    public required string Name { get; set; }
    public required DateTime Birthday { get; init; }

    public int Age
    {
        get
        {
            return new DateTime(DateTime.Now.Subtract(Birthday).Ticks).Year;
        }
    }
}

 

마지막으로 with 키워드에 대해 알아볼게요!

with 키워드는 클래스 안에 프로퍼티 종류가 많을때

중복되는 초기화 값들을 초기화 할때 유용해요!

 

아래 코드를 볼게요~

주석으로 설명 추가합니다!

record WithExp
{
    public string From { get; init; }
    public string To { get; init; }
    public int Amount { get; init; }

    public override string ToString()
    {
        return $"{From} ->  {To} : ${Amount}";
    }
}

class MainApp
{
    static void Main(string[] args)
    {
        RTransaction tr1 = new RTransaction
        {
            From = "Alice",
            To = "Bob",
            Amount = 100
        };
        RTransaction tr2 = tr1 with { To = "Charlie" }; // tr1의 모든 값들을 똑같이 초기화하고 To만 변경하겠다는 말이에요!
        RTransaction tr3 = tr2 with { From = "Dave", Amount = 30 }; // tr2의 모든 값들을 똑같이 초기화하고 From, Amount만 변경하겠다는 말이에요!

        Console.WriteLine(tr1);
        Console.WriteLine(tr2);
        Console.WriteLine(tr3);
    }
}

 

'C#' 카테고리의 다른 글

[C#] 컬렉션  (0) 2024.10.07
[C#] 배열  (0) 2024.10.07
[C#] 얕은 복사와 깊은 복사 - 설명 및 예제 코드  (0) 2024.10.05
[C#] ref out 키워드 의미 및 예시 코드  (4) 2024.10.03
[C#] 박싱과 언박싱  (0) 2024.10.01