참치김밥은 최고의 한식이다

[Effective C# 2판] Item 1 : 접근 가능한 데이터 멤버 대신 속성을 사용하라 본문

책/C#

[Effective C# 2판] Item 1 : 접근 가능한 데이터 멤버 대신 속성을 사용하라

l__j__h 2024. 2. 21. 09:30

본문은 Effective C# 2판을 읽고 정리한 글입니다!!

더보기

유연한 C# 코드를 짜고 싶다

코드 리팩토링을 어떻게 해야 할 지 모르겠다

객체 지향적 설계를 하고 싶다

등등 여러 고민을 안고 있다면 이 책 추천드립니다... 👍👍

 

Item 1 : 접근 가능한 데이터 멤버 대신 속성을 사용하라

개요

멤버 중에는 데이터로 표현해야 어울리는 것이 있다. 예를 들면 고객 이름, 좌표, 매출 등이 그렇다. 이럴 때 속성을 사용하면 데이터 필드에 직접 접근하는 것처럼 실행되면서도 메서드가 주는 이점을 그대로 취할 수 있다. 클라이언트 코드에서는 속성이 마치 public 데이터 필드인 듯 사용하겠지만, 실제로는 속성 접근자 메서드를 호출하게 된다.

 

속성(Property)을 사용하면, 향후에 요구사항이 변경되어 코드를 수정해야 하는 경우에도 용이하다.

예를 들어, ‘고객 이름은 비어서는 안 된다’는 새로운 요구사항이 생겼다고 하자. Name을 public 속성으로 선언하였다면, 단 한 곳만 수정하면 되기 째문에 이 요구사항을 아주 쉽게 반영할 수 있다.

public class Customer{
	private string name;
	public string Name{
		get => name;
		//요구사항이 변경되면 아래 예외처리 코드만 추가해주면 된다.
		set{
			if(string.IsNullOrWhitespace(value))
				throw new ArgumentException("Name cannot be blank", nameof(Name));
			name = value;
}
}
}

만약 프로퍼티가 아니라, public 데이터 멤버를 사용했다면, 전체 코드를 살펴보고, 고객 이름을 설정하는 코드를 모두 찾아 수정해야 하는데, 코드를 수정하는 시간보다 수정해야 하는 코드를 찾느라 훨씬 많은 시간을 소비할 것이다.

 

인덱서

예시

public int this[int index]{
	get => theValues[index];
	set => theValues[index] = value;
}

private int[] theValues = new int[100];

//인덱서에 접근
int val = someObject[i];

인덱서는 일반적인 프로퍼티가 제공하는 기능을 모두 지원한다.

인덱서는 맵(Dictionary 같은 자료형)을 정의할 때에도 유용하다.

public Address this[string name]{
	get => addressValues[name];
	set => addressValues[name] = value;
}

private Dictionary<string, Address> addressValues;

 

C#의 다차원 배열처럼 다차원 인덱서를 만들 수도 있다. 아래와 같이 다양한 타입을 받아 값을 반환시킬 수 있다.

public int this[int x, int y] => ComputeValue(x, y);
public int this[int x, string name] => ComputeValue(x, name);

 

이때, 모든 인덱서는 this 키워드로 선언해야 한다. C#에서는 인덱서가 이름을 가질 수 없다. 따라서 여러 개의 인덱서를 선언하려면 각기 매개변수 목록이 달라야 한다.

 

 

프로퍼티 사용할 때 지켜야 할 것

  • get 접근자는 상태를 변경하면 안 되고, set 접근자는 상태를 변경하고 그 결과를 사용자가 볼 수 있어야 한다.
  • 프로퍼티를 사용할 때에, 우리 모두는 성능이 나빠지지 않길 바랄 것이다. 특히, 프로퍼티를 사용하는 코드는 마치 데이터 필드에 직접 접근하는 것처럼 보이므로, 성능 면에서 큰 차이를 보이면 안 된다. 따라서, 프로퍼티 접근자 내에서는 시간이 오래 걸리는 연산을 수행하거나, 다른 앱을 호출(DB 쿼리 같은)하는 작업을 수행해서는 안 된다. 이는 우리가 작성한 프로퍼티를 쓸 사용자가 기대하는 일관성을 해치는 짓이다.

 

Item2로 이어집니다.

728x90