반응형
해당 포스팅은 개인적으로 C# WPF를 공부하면서 익힌 내용을 기억에 남기기 위한 작업의 일환으로 작성된 글로서 일부 내용에 오류가 있을 수도 있으니 참고하시기 바랍니다.

 

C# WPF의 비하인드 코드에서 자주 등장하는
필드와 속성에 대한 개념에 대해 이해하고,
get/set 키워드의 동작에 대해
알아보자.

내용 요약

 

C# WPF에서는 필드와 속성이라는 개념이 있는데,

코드의 캡슐화와 데이터 무결성을 위해

필드에 접근할 때에는

속성(property)을 이용할 것을 권장하고 있으며

이런 속성을 이용함으로서

데이터의 유효성 검증부터 읽기/쓰기 전용 접근 제어

그리고 데이터 변경에 대한 로깅 및 이벤트 트리거링 등의

추가 기능을 쉽게 구현할 수 있다.

따라서, 필드와 속성의 개념을 정확히 알고 프로그래밍 하는 것이 중요하다.

본 포스팅에서는 이러한 내용과 개념에 대해 예를 들어가며

설명하도록 하겠다.

(해당 포스팅은 아래의 링크를 참조하여 작성하였다.)

 

https://learn.microsoft.com/ko-kr/dotnet/csharp/programming-guide/classes-and-structs/fields?source=recommendations

 

필드 - C#

C#의 필드는 클래스 또는 구조체에서 직접 선언되는 모든 형식의 변수입니다. 필드는 포함하는 형식의 멤버입니다.

learn.microsoft.com

 

https://learn.microsoft.com/ko-kr/dotnet/csharp/programming-guide/classes-and-structs/properties?source=recommendations

 

속성 - C#

C#의 속성은 접근자 메서드를 사용하여 공용 데이터 멤버인 것처럼 private 필드의 값을 읽고, 쓰고, 계산하는 멤버입니다.

learn.microsoft.com

 

목차
1.필드의 정의
2.속성의 정의
3.실습 예제 및 실행 결과

 

1.필드의 정의

필드(Field)는 클래스 또는 구조체에서 직접 선언되는

모든 형식의 변수이다.

일반적으로 필드는 private 또는 protected, public 등의

접근성을 선언해 주어야 한다.

public class Family
{
    private string _firstName = "gildong";    // 필드 (접근성 : private)
    private string _lastName = "Kim";
    private int _age = 30;
}

 

위의 예시에서처럼 _firstName, _lastName, _age는

모두 private 접근 지정자로 선언된

변수수로서

클래스 외부에서는 접근이 불가능한

필드(field)이다.

이러한 필드는 method, property, Indexer등을 통해

접근하도록 해야 잘못된 입력값으로부터 보호할 수 있으며,

선언할 때 연산자를 사용하여 초기값을 지정할 수 있다.

각 필드는 "gildong", "Kim", 30으로

초기화 되었다.

만약, 접근 지정자가 public으로 되어있다면,

클래스 외부에서 인스턴스(객체)의 필드에 접근할 때는

객체 이름 뒤에 마침표를 추가하고 그 뒤에 필드 이름을 추가하면 된다.

public class Family
{
    public string _firstName = "gildong";    // 필드 (접근성 : private)
    public string _lastName = "Kim";
    public int _age = 30;
}
int main()
{
    Family family;
    family._firstName = "hongja";
    family._lastName = "Choi";
    family._age = 27;
}

 

2.속성의 정의

 

속성이란 필드의 값을 읽거나 쓰거나 계산하는

유연한 메커니즘을 제공하는 멤버이다.

속성은 공용 데이터 멤버인 것처럼 사용할 수 있지만

"접근자"라는 특수 메서드 이다.

이 기능은 데이터의 안전성과 유연성을 높이는데 도움이 되며,

이 기능을 통해 privat로 선언된 필드를

외부에서 접근이 가능하도록 할 수 있다.

마치 publi으로 선언하는 것과 별반 차이가 없어 보일 수도 있으나,

속성을 사용하는 이유는

값을 변경하거나 가져올 때,

조건을 통해 필드에 대한 접근을 콘트롤 할 수 있기 때문이다.

 

public class Family
{
    private string _firstName = "gildong";    // 필드 (접근성 : private)
    public string FirstName      // 속성 (접근성 : public)
    {
        get { return _firstName; }   // get method : 필드의 값을 얻고자 할때
        set                          // set method : 필드에 값을 대입하고자 할때
        {
            _firstName = value;  // value(키워드) : 내장 변수로서 프로퍼티에 할당된 실제 값을 나타냄
        }
    }
}

 

위와 같이 Family class내에 _firstName이 "gilDong"으로 초기화 되어있으며,

접근 지정자는 private으로서 클래스 외부에서는

접근이 불가하지만,

FirstName이라는 속성(property)을 정의하고,

get/set method를 정의함으로서

외부에서 간접적으로 _firstName에 접근(read,write)하는 것이

가능하다.

여기에서, 아래 표와 같이

get 혹은 set metho의 정의 여부에 따라

읽기 전용 혹은 쓰기 전용으로 Property를 만드는 것도 가능하다.

접근 가능성
구현 방법
ro/rw
get/set method를 모두 정의
ro
get method만 정의
rw
set method만 정의

이러한 필드(field)와 속성(property)을 아래 실습 예제를 통해 알아보자.

 

3.실습 예제 및 실행 결과

 

실습을 하기에 앞서 프로젝트 생성은 아래와 같이 해주었다.

Visual Studio에서 New Project를 선택 후

아래와 같이 language는 C#, Template는 Console Application

으로 한다.

 

아래 예제에서와 같이

_firstName, _lastName, _address, _familyMember등이

모두 private으로 설정되어 있어서

사실상 외부에서 접근이 불가능한 필드이지만, 각각이

FirstName, LastName, Address, FamilyMember라는 속성을 가지고 있으며,

또한 get/set method를 정의하였기 때문에

외부에서의 접근이 가능하다.

 

using System;

public class Family
{
    private string _firstName = "KilDong";    // 필드 (접근성 : private)

    public string FirstName      // 속성 (접근성 : public)
    {
        get { return _firstName; }   // get method : 필드의 값을 얻고자 할때
        set
        {                               // set method : 필드에 값을 대입하고자 할때
            _firstName = value;  // value(키워드) : 내장 변수로서 프로퍼티에 할당된 실제 값을 나타냄
        }
    }

    private string _lastName = "Kim";
    public string LastName
    {
        get { return _lastName; }
        set
        {
            _lastName = value;
        }
    }

    private int _age = 30;
    public int Age
    {
        get { return _age; }
        set
        {
            _age = value;
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        Family familyObj = new Family();
        Console.WriteLine(“Before familyObj.Age set : " + familyObj.Age);
        familyObj.Age = 20;
        Console.WriteLine(“After familyObj.Age set : " + familyObj.Age);
    }
}

 

위 코드를 실행하면,

아래와 같이 객체 familyObj는 초기에

_age가 30으로 초기화 되었다가

속성 Age를 통해 값 '20'이 write되어

'20'으로 변경되는 것을 확인할 수 있다.

여기에서 set method에 조건을 추가하여

필드에 값을 write하는 경우

특정 범위를 벗어날 때(0보다 작은 경우) 값의 입력이 안되도록

코드를 변경해 보자.

이를 위해 _age 필드의 속성 Age에 대해

set metho를 아래와 같이 수정하였다.

private int _age = 30;
public int Age
{
    get { return _age; }
    set
    {
        if (value < 0) {Console.WriteLine(“Invalid value”); }
        else _age = value;
    }
}

 

class Program
{
    static void Main(string[] args)
    {
        Family familyObj = new Family();
        Console.WriteLine("Before familyObj.Age set: " + familyObj.Age);
        familyObj.Age = -2;
        Console.WriteLine("After familyObj.Age set: " + familyObj.Age);
    }
}

 

실행 결과,

초기에 설정된 값 30이 변경되지 않고 그대로 있는 것을 확인 할 수 있다.

마찬가지로 get method에 대해서도 조건을 추가하여

필드의 값을 읽을 수 없도록 설정하는 것이 가능하다.

이를 위해 _age필드에 대한 Age속성의 get method를

아래와 같이 수정하고 실행해 보도록 하자.

 

private int _age = 30;
public int Age
{
    get
    {
        if (_age == 50) { return 0; }
        else { return _age; }
    }
    set
    {
        if (value < 0) { Console.WriteLine("Invalid value : " + value); }
        else _age = value;
    }
}

 

class Program
{
    static void Main(string[] args)
    {
        Family familyObj = new Family();
        Console.WriteLine("Before familyObj.Age set: " + familyObj.Age);
        familyObj.Age = -2;
        Console.WriteLine("After familyObj.Age set: " + familyObj.Age);

        familyObj.Age = 50;
        Console.WriteLine("After familyObj.Age set: " + familyObj.Age);
    }
}

 

실행결과,

Age를 통해 _age 필드를 50으로 set하였으나,

get method에서 조건(50일 경우 0을 리턴)에 의해

Age를 읽을 때 0으로 출력되는 것을 확인할 수 있다.

이러한 Property는 필드가 10개 이상만 되어도

코드가 매우 길어지며, 귀찮은 일이 될 것이다.

따라서, 단순히 읽고 쓰기만 하는 경우 일일이 구현할 필요 없이 자동으로

구현되게 해주는 방법도 있다.

바로 아래 소스 처럼 필드정의 시에 get과 set만 추가 해주면 된다.

 

private string –firstName { get; set; } = “초기값”;

 

 

 

 

"

마치며...

필드(field)와 속성(property)의 정의에 대해

알 수 있었고, 동작 원리에 대해 이해할 수 있었다.

"

반응형

+ Recent posts