멤버
- 클래스는 나만의 타입을 만들 수 있는 도구
- 클래스는 여러 가지 멤버(Member)로 표현, 멤버는 클래스의 구성 요소
- 멤버의 종류 : 필드, 상수, 프로퍼티, 메소드, 이벤트, 연산자, 인덱서, 생성자, 종료자, 네스티드 타입
- 이 중에서 필드, 상수, 메소드, 프로퍼티, 생성자만 우선 다룸

필드
- 필드는 클래스 범위에 선언된 변수로 해당 타입을 구성하는 데이터
- 필드는 일반적으로 클래스의 부품 역할을 하며 대부분 private 한정자가 붙음
- 필드는 클래스가 가지는 속성이며 변수 또는 상수가 위치
- 클래스의 부품 역할을 하는 클래스의 내부 상태 값을 저장해놓는 그릇

상수
- 상수도 멤버로 추가할 수 있지만, 필드와는 달리 내장 타입(Object는 예외)만 가능
- 내장 타입이 아닌 것들은 붙일 수 없음
메소드
- 함수로 클래스가 할 수 있는 행위를 정의
- 클래스를 만들면 보통 필드를 직접 수정하기보다는 메소드를 호출해 데이터를 조작하는 것이 일반적
- 메소드 내부의 데이터를 직접적으로 사용하는 경우는 흔치 않음
- 메소드는 같은 이름을 사용할 수 있지만, 시그니처가 달라야 함
- 시그니처는 함수의 입력과 출력을 정의하고, 접근 수준, 한정자, 반환값, 함수의 이름, 함수의 매개변수로 구성
- 같은 이름의 메소드를 사용하려면 매개변수를 다르게 하면 됨
- 같은 이름의 메소드를 사용하는 기능을 오버로딩이라고 하며, 입력되는 데이터를 다르게 할 때나 헬퍼 함수를 정의하는 데 사용할 수 있음
- 오버로딩 기능을 사용하려면 public, void, int 등의 메소드 앞의 반환타입을 다르게 하는 것이 아니라 괄호안의 매개변수를 다르게 해야 오버로딩 기능을 사용 가능


(헬퍼 함수의 예시이고, 위쪽에 선언된 매개변수가 더 적은 Count 메소드가 헬퍼 함수)
프로퍼티
- 우리가 정의해놓은 데이터를 직접적으로 수정하고 사용한다면 오류가 발생할 확률도 높고 설계자가 의도한대로 사용하지 않을 수도 있으니, 대부분의 상황에서는 메소드를 통해서 데이터를 간접적으로 사용
- 하지만 가끔은 데이터에 직접 접근할 수 있는 메소드를 정의해야 할 때가 있음
- 데이터를 수정할 수 있는 메소드를 Setter, 데이터에 접근할 수 있는 메소드를 Getter라고 함
- 매번 Setter와 Getter를 입력하는 것은 귀찮기 때문에 C#에서 제공하는 편리한 기능이 프로퍼티(Property)
- 프로퍼티는 메소드이기 때문에, 프로퍼티도 오버헤드가 있음
- 아래의 그림이 프로퍼티의 예시. 오른쪽과 왼쪽은 동일함.


(위에서는 _atk에 getter, setter를 생성해 주지 않았고 아래에서는 생성해 주었기에, 그 부분만 차이점이 있고 나머지는 전부 동일)
생성자
- 생성자(Constructor)는 객체의 데이터를 초기화하는 메소드
- 반환값이 없고, 이름이 타입의 이름과 같음
- 보통은 명시적으로 무언가를 나타내줘야하는 경우에만 사용
- 생성자는 명시적으로 정의해주지 않아도 C#이 알아서 매개변수가 없는 생성자를 만들어 줌
- 생성자 또한 메소드이기에 오버로딩이 가능

readonly 한정자
- 상수처럼 클래스 타입도 더 이상 수정되지 않길 원한다면 readonly 한정자를 사용할 수 있음
- 필드를 정의할 때 붙일 수 있으며, 변수에 붙이는 것이 아님
- 해당 필드는 생성자 안에서만 값을 할당할 수 있음
- 생성자 범위 밖에서 데이터를 할당하려고 하면 오류가 발생

this 포인터
- 인스턴스끼리는 데이터가 독립적 (독립적이기에 서로 영향을 주지 않음)
- this 포인터는 인스턴스 메소드에서만 유효함
- this를 명시적으로 적어주는 경우는 없지만 어떻게 동작하는지는 알아야 함
정적 멤버
- static 한정자를 사용하면 멤버를 정적으로 만들 수 있음
- 정적 멤버가 되면 인스턴스끼리 공유하는 멤버가 됨
- 정적 생성자는 생성자에 static을 붙임
- 정적 멤버는 클래스 이름을 통해서만 접근할 수 있음
- 정적 필드는 스택 영역 혹은 힙 영역을 사용하지 않고, 데이터 영역을 사용
- 정적 멤버만을 모아놓기 위해 정적 클래스를 만들 수 있는데, 이 경우에는 인스턴스를 만드는 것이 불가능
- 정적 필드를 초기화하기 위해 정적 생성자를 사용할 수 있음
- 제한 사항 (정적 필드를 초기화하기 위해 정적 생성자를 사용하는데 따르는 제한)
- 접근 한정자 및 매개변수를 가지지 않음
- 오직 하나만 존재
- 직접적으로 호출할 수 없음. CLR에 의해서만 자동으로 호출
- 실행 시점을 사용자가 제어할 수 없고, 첫 인스턴스가 생성되기 전 혹은 정적 멤버가 참조되기 전에는 무조건 호출
- 인스턴스 생성자가 호출되기 전에 정적 생성자가 실행
확장 메소드
- 확장 메소드는 무조건 정적 메소드(static)
- 이미 존재하는 타입에 우리의 메소드를 추가할 수 있는데, 이를 확장 메소드라고 함
- 확장 메소드를 이용하면 마치 원래 있던 메소드처럼 사용할 수 있음
- 확장 메소드의 첫 번째 매개변수는 확장시킬 타입의 매개변수여야 하며, 앞에 this 키워드(this 포인터)를 붙임
