속성(C# 프로그래밍 가이드)
속성은 데이터 필드의 값을 읽거나 쓰거나 계산하는 유연한 메커니즘을 제공하는 멤버입니다. 속성은 공용 데이터 멤버로 표시되지만, 접근자라는 특수 메서드로 구현됩니다. 이 기능을 통해 호출자는 데이터에 쉽게 액세스할 수 있으며 데이터 안전성과 유연성 수준을 올리는 데에도 도움이 됩니다. 속성 구문은 필드에 대한 자연 확장입니다. 필드는 스토리지 위치를 정의합니다.
public class Person
{
public string? FirstName;
// Omitted for brevity.
}
자동으로 구현된 속성
속성 정의에는 해당 속성의 값을 검색하고 할당하는 get
및 set
접근자에 대한 선언이 포함됩니다.
public class Person
{
public string? FirstName { get; set; }
// Omitted for brevity.
}
앞의 예제에서는 자동으로 구현된 속성을 보여줍니다. 컴파일러는 속성에 대한 숨겨진 지원 필드를 생성합니다. 또한 컴파일러는 get
및 set
접근자의 본문을 구현합니다. 모든 특성은 자동으로 구현된 속성에 적용됩니다. 특성에 field:
태그를 지정하여 컴파일러 생성 지원 필드에 특성을 적용할 수 있습니다.
속성에 대한 닫는 중괄호 뒤의 값을 설정하여 기본값이 아닌 값으로 속성을 초기화할 수 있습니다. FirstName
속성의 초기 값을 null
대신 빈 문자열로 설정할 수도 있습니다. 다음 코드와 같이 지정할 수 있습니다.
public class Person
{
public string FirstName { get; set; } = string.Empty;
// Omitted for brevity.
}
필드 백업 속성
C# 13에서는 키워드 미리 보기 기능을 사용하여 속성에 대한 접근자에서 유효성 검사 또는 기타 논리를 field
추가할 수 있습니다. 키워드는 field
속성에 대한 컴파일러 합성 지원 필드에 액세스합니다. 이를 통해 별도의 지원 필드를 명시적으로 선언하지 않고 속성 접근자를 작성할 수 있습니다.
public class Person
{
public string? FirstName
{
get;
set => field = value.Trim();
}
// Omitted for brevity.
}
Important
field
키워드는 C# 13의 미리 보기 기능입니다. 상황별 키워드를 사용하려면 .NET 9를 preview
사용하고 field
프로젝트 파일에서 요소를 설정 <LangVersion>
해야 합니다.
이름이 지정된 field
필드가 field
있는 클래스에서 키워드 기능을 사용하는 데 주의해야 합니다. 새 field
키워드는 속성 접근자의 범위에 명명된 field
필드를 숨깁니다. 변수의 field
이름을 변경하거나 토큰을 사용하여 @
식별자를 .로 @field
참조 field
할 수 있습니다. 키워드에 대한 field
기능 사양을 읽어 자세히 알아볼 수 있습니다.
필수 속성
앞의 예제에서는 호출자가 FirstName
속성을 설정하지 않고 기본 생성자를 사용하여 Person
을 만들 수 있습니다. 속성이 형식을 nullable 문자열로 변경했습니다. C# 11부터 호출자가 속성을 설정하도록 요청할 수 있습니다.
public class Person
{
public Person() { }
[SetsRequiredMembers]
public Person(string firstName) => FirstName = firstName;
public required string FirstName { get; init; }
// Omitted for brevity.
}
앞의 코드는 Person
클래스에서 두 가지를 변경합니다. 먼저, FirstName
속성 선언에는 required
한정자가 포함되어 있습니다. 즉, 새로운 Person
을 만드는 코드 모든 코드는 개체 이니셜라이저를 사용하여 이 속성을 설정해야 합니다. 둘째, firstName
매개 변수를 사용하는 생성자에는 System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute 특성이 있습니다. 이 특성은 이 생성자가 모든required
멤버를 설정한다는 것을 컴파일러에 알립니다. 이 생성자를 사용하는 호출자는 개체 이니셜라이저로 required
속성을 설정할 필요가 없습니다.
Important
required
와 null을 허용하지 않음을 혼동하지 마세요. required
속성을 null
또는 default
로 설정하는 것이 유효합니다. 이 예의 string
과 같이 형식이 null을 허용하지 않는 경우 컴파일러는 경고를 발급합니다.
var aPerson = new Person("John");
aPerson = new Person{ FirstName = "John"};
// Error CS9035: Required member `Person.FirstName` must be set:
//aPerson2 = new Person();
식 본문 정의
속성 접근자는 한 줄 문으로 구성되는 경우가 많습니다. 접근자가 식의 결과를 할당하거나 반환합니다. 이러한 속성은 식 본문 멤버로 구현할 수 있습니다. 식 본문 정의는 =>
토큰과 속성에 할당하거나 속성에서 검색할 식으로 구성됩니다.
읽기 전용 속성은 get
접근자를 식 본문 멤버로 구현할 수 있습니다. 다음 예제에서는 읽기 전용 Name
속성을 식 본문 멤버로 구현합니다.
public class Person
{
public Person() { }
[SetsRequiredMembers]
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
public required string FirstName { get; init; }
public required string LastName { get; init; }
public string Name => $"{FirstName} {LastName}";
// Omitted for brevity.
}
Name
속성은 계산된 속성입니다. Name
에 대한 지원 필드가 없습니다. 속성은 매번 계산합니다.
Access Control
앞의 예제에서는 읽기/쓰기 속성을 살펴보았습니다. 읽기 전용 속성을 만들거나 set 및 get 접근자에 대해 다른 액세스 가능성을 제공할 수도 있습니다. 클래스에서 Person
속성 값을 클래스의 FirstName
다른 메서드에서만 변경할 수 있도록 설정해야 한다고 가정합니다. 다음 대신 set 접근자 private
접근성을 internal
제공할 수 있습니다 public
.
public class Person
{
public string? FirstName { get; private set; }
// Omitted for brevity.
}
FirstName
속성을 모든 코드에서 읽을 수 있지만 Person
클래스의 코드에서만 할당할 수 있습니다.
set 또는 get 접근자에 제한적인 액세스 한정자를 추가할 수 있습니다. 개별 접근자에 대한 액세스 한정자는 속성의 액세스보다 더 제한적이어야 합니다. 위의 코드는 FirstName
속성이 public
이지만 set 접근자가 private
이므로 유효합니다. public
접근자를 사용하여 private
속성을 선언할 수 없습니다. 속성 선언을 protected
, internal
, protected internal
또는 private
로 선언할 수도 있습니다.
set
접근자에 대해 두 가지 특수 액세스 한정자가 있습니다.
set
접근자는 액세스 한정자로init
을 사용할 수 있습니다. 해당set
접근자는 개체 이니셜라이저 또는 형식의 생성자에서만 호출할 수 있습니다.set
접근자의private
보다 더 제한적입니다.- 자동으로 구현된 속성은 접근자 없이 접근자를 선언할
get
set
수 있습니다. 이 경우 컴파일러는 형식의 생성자에서만set
접근자를 호출할 수 있습니다.set
접근자의init
접근자보다 더 제한적입니다.
다음과 같이 Person
클래스를 수정합니다.
public class Person
{
public Person(string firstName) => FirstName = firstName;
public string FirstName { get; }
// Omitted for brevity.
}
앞의 예에서는 호출자가 FirstName
매개 변수를 포함하는 생성자를 사용해야 합니다. 호출자는 개체 이니셜라이저를 사용하여 속성에 값을 할당할 수 없습니다. 이니셜라이저를 지원하려면 다음 코드에 표시된 대로 set
접근자를 init
접근자로 만들 수 있습니다.
public class Person
{
public Person() { }
public Person(string firstName) => FirstName = firstName;
public string? FirstName { get; init; }
// Omitted for brevity.
}
이러한 한정자는 적절한 초기화를 강제로 적용하기 위해 required
한정자와 함께 사용되는 경우가 많습니다.
지원 필드가 있는 속성
계산된 속성의 개념과 프라이빗 필드를 혼합하고 캐시된 평가 속성을 만들 수 있습니다. 예를 들어 첫 번째 액세스에서 문자열 서식이 지정되도록 FullName
속성을 업데이트합니다.
public class Person
{
public Person() { }
[SetsRequiredMembers]
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
public required string FirstName { get; init; }
public required string LastName { get; init; }
private string? _fullName;
public string FullName
{
get
{
if (_fullName is null)
_fullName = $"{FirstName} {LastName}";
return _fullName;
}
}
}
FirstName
및 LastName
속성이 읽기 전용이므로 이 구현이 작동합니다. 사용자는 자신의 이름을 변경할 수 있습니다. set
접근자를 허용하도록 FirstName
및 LastName
속성을 업데이트하려면 fullName
의 캐시된 값을 무효화해야 합니다. fullName
필드가 다시 평가되도록 FirstName
및 LastName
속성의 set
접근자를 수정합니다.
public class Person
{
private string? _firstName;
public string? FirstName
{
get => _firstName;
set
{
_firstName = value;
_fullName = null;
}
}
private string? _lastName;
public string? LastName
{
get => _lastName;
set
{
_lastName = value;
_fullName = null;
}
}
private string? _fullName;
public string FullName
{
get
{
if (_fullName is null)
_fullName = $"{FirstName} {LastName}";
return _fullName;
}
}
}
이 최종 버전은 필요한 경우에만 FullName
속성을 평가합니다. 유효한 경우 이전에 계산한 버전이 사용됩니다. 그렇지 않으면 계산이 캐시된 값을 업데이트합니다. 이 클래스를 사용하는 개발자는 구현 세부 정보를 알 필요가 없습니다. 이러한 내부 변경 내용은 Person 개체의 사용에 영향을 주지 않습니다.
C# 13부터 partial
클래스에서 partial
속성을 만들 수 있습니다. 속성에 대한 구현 선언은 partial
자동으로 구현된 속성이 될 수 없습니다. 자동으로 구현된 속성은 선언 부분 속성 선언과 동일한 구문을 사용합니다.
속성
속성은 클래스 또는 개체에 있는 스마트 필드의 한 형태입니다. 개체 외부에서는 개체의 필드와 유사하게 나타납니다. 그러나 C# 기능의 전체 팔레트를 사용하여 속성을 구현할 수 있습니다. 유효성 검사, 다른 액세스 가능성, 지연 평가 또는 시나리오에 필요한 모든 요구 사항을 제공할 수 있습니다.
- 사용자 지정 접근자 코드가 필요하지 않은 단순 속성은 식 본문 정의 또는 자동으로 구현된 속성으로 구현할 수 있습니다.
- 속성을 사용하면 클래스가 구현 또는 검증 코드를 숨기는 동시에 값을 가져오고 설정하는 방법을 공개적으로 노출할 수 있습니다.
- get 속성 접근자는 속성 값을 반환하는 데 사용되고 set 속성 접근자는 새 값을 할당하는 데 사용됩니다. init 속성 접근자는 개체 생성 중에만 새 값을 할당하는 데 사용됩니다. 이러한 접근자는 각기 다른 액세스 수준을 가질 수 있습니다. 자세한 내용은 접근자 액세스 가능성 제한을 참조하세요.
- 값 키워드는
set
또는init
접근자가 할당하는 값을 정의하는 데 사용됩니다. - 속성은 읽기/쓰기(
get
및set
접근자 모두 포함), 읽기 전용(get
접근자는 포함하지만set
접근자는 포함 안 함) 또는 쓰기 전용(set
접근자는 포함하지만get
접근자는 포함 안 함)일 수 있습니다. 쓰기 전용 속성은 거의 없습니다.
C# 언어 사양
자세한 내용은 C# 언어 사양의 속성을 참조하세요. 언어 사양은 C# 구문 및 사용법에 대 한 신뢰할 수 있는 소스 됩니다.
참고 항목
.NET