Field
(이하 필드)는 클래스 내부에 선언된 변수이다.
필드는 기본적으로 클래스의 속성을 나타내는데 사용된다.
Property
(이하 프로퍼티)는 필드의 접근자, 설정자 메서드를 제공하는 것이다.
일반적으로 클래스의 필드는 외부에 공개되지 않도록 제한한다.
따라서, 필드 즉 속성에 접근하려면 접근자 혹은 설정자를 통해 속성에 접근할 수 있다.
이러한 접근자를 제공하는 역할이 프로퍼티인 것이다.
지난 포스팅에서
namespace netAPI.Models;
public class User
{
public int UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Gender { get; set; }
public bool Active { get; set; }
public User()
{
if (FirstName == null) FirstName = "";
LastName ??= "";
Email ??= "";
Gender ??= "";
}
}
User
클래스의 모든 필드가 public
으로 선언되었다고 착각하여
namespace netAPI.Models;
public class User
{
private int _UserId;
private string _FirstName;
private string _LastName;
private string _Email;
private string _Gender;
private bool _Active;
public int UserId
{
get { return _UserId; }
set { _UserId = value; }
}
public string FirstName
{
get { return _FirstName; }
set { _FirstName = value ?? ""; }
}
public string LastName
{
get { return _LastName; }
set { _LastName = value ?? ""; }
}
public string Email
{
get { return _Email; }
set { _Email = value ?? ""; }
}
public string Gender
{
get { return _Gender; }
set { _Gender = value ?? ""; }
}
public bool Active
{
get { return Active; }
set { _Active = value; }
}
public User() { }
위와 같이 리팩토링을 하였고, 결과적으로 순환 참조 오류가 발생하였다.
순환 참조의 발생 지점은 get {return Active;}
에서 발생하였다.
우리는 필드를 _Active
로 선언하였기 때문에, _Active
필드를 참조하기 위해 프로퍼티의 접근자를 호출했을 때, 접근자를 다시 호출하는 오류가 발생한 것이다.
아무튼 오타에서 비롯한 오류였고, 코드에는 이상이 없었다.
하지만, 알아야할 점은 리팩토링한 코드와 기존의 코드는 정확히 동일하게 동작한다는 점이었다.
public int UserId { get; set; }
private int _userId;
public int UserId{
get { return _userId; }
set { _userId = value; }
}
위 두 코드는 정확하게 동일한 코드이며, 동일하게 동작한다.
public int UserId { get; set; }
이라는 코드가 아래와 같이 필드와 프로퍼티 선언을 자동으로 생성 해주는 것이었다.
필드라고 착각했던 것이 실제로는 프로퍼티이고, 이것이 자동으로 private
필드를 생성해주었다.
문제 해결👍