자동 특성과 구조가 혼합되지 않습니까?
-
05-07-2019 - |
문제
대답하는 동안 작은 구조물을 걷어차 고 이 게시물, 나는 예기치 않게 다음을 발견했다.
INT 필드를 사용하는 다음 구조는 완벽하게 합법적입니다.
struct MyStruct
{
public MyStruct ( int size )
{
this.Size = size; // <-- Legal assignment.
}
public int Size;
}
그러나 자동 속성을 사용하는 다음 구조는 다음과 같습니다.
struct MyStruct
{
public MyStruct ( int size )
{
this.Size = size; // <-- Compile-Time Error!
}
public int Size{get; set;}
}
반환 된 오류는 "이 객체는 모든 필드가 할당되기 전에"이 객체를 사용할 수 없습니다 "입니다. 이것은 구조물의 표준 절차라는 것을 알고 있습니다. 구조물의 생성자 내에서 모든 속성의 후원 필드는 구조물의 생성자 내에서 직접 지정되어야합니다 (재산의 세트 액세서를 통해).
솔루션은 명시 적 뒷면 필드를 사용하는 것입니다.
struct MyStruct
{
public MyStruct(int size)
{
_size = size;
}
private int _size;
public int Size
{
get { return _size; }
set { _size = value; }
}
}
(vb.net은 VB.NET에서 모든 필드가 자동으로 0/null/false로 자동 초기화되기 때문에이 문제가 없을 것입니다.)
이것은 C#의 structs와 함께 자동 속성을 사용할 때 불행한 한계 인 것 같습니다. 개념적으로 생각하면, 나는 이것이 적어도 자동 속성에 대해 속성 세트 액세서를 구조물의 생성자 내에서 호출 할 수있는 예외가 될 수있는 합리적인 장소가 될 수 없는지 궁금했습니다.
이것은 거의 사소한 문제, 거의 가장자리 가지만, 다른 사람들이 이것에 대해 어떻게 생각하는지 궁금했습니다 ...
해결책
C# 6에서 : 이것은 더 이상 문제가되지 않습니다.
CORE C# 6이 작동하려면 기본 생성자를 호출해야합니다.
public MyStruct(int size) : this()
{
Size = size;
}
여기서 더 큰 문제는 당신이 돌연변이 가능한 구조물이 있다는 것입니다. 이것은 절대 좋은 아이디어. 나는 그것을 만들 것이다 :
public int Size { get; private set; }
아니다 기술적으로 불변이지만 충분히 가깝습니다.
최근 버전의 C#을 사용하면 다음을 향상시킬 수 있습니다.
public int Size { get; }
이것은 이제 할 수 있습니다 뿐 생성자에 할당됩니다.
다른 팁
먼저 기본 생성자를 호출 하여이 문제를 해결할 수 있습니다.
struct MyStruct
{
public MyStruct(int size) : this()
{
this.Size = size; // <-- now works
}
public int Size { get; set; }
}
이 문제에 대한 또 다른 모호한 작업은 임시에서 발견 된 것입니다. Tuple
수업 관리 확장 성 프레임 워크 (을 통해 krzysztof koakic):
public struct TempTuple<TFirst, TSecond>
{
public TempTuple(TFirst first, TSecond second)
{
this = new TempTuple<TFirst, TSecond>(); // Kung fu!
this.First = first;
this.Second = second;
}
public TFirst First { get; private set; }
public TSecond Second { get; private set; }
(CodePlex의 전체 소스 코드 : tuple.cs)
또한 문서에 주목합니다 CS0188 추가로 업데이트되었습니다.
구조물 생성자에서 속성을 초기화하려고 할 때이 오류가 표시되면 솔루션은 생성자 매개 변수를 변경하여 속성 자체 대신 백킹 필드를 지정하는 것입니다. 자동 구현 된 특성은 백업 필드가 없으므로 생성자로부터 어떤 식 으로든 초기화 할 수 없기 때문에 스트러크에서 피해야합니다.
따라서 공식적인 지침은이 문제에 빠질 때 구조 스타일 속성을 사용하는 것임을 의미합니다. 이는 지금까지 탐색 한 다른 두 대안 중 하나보다 덜 모호하고 더 읽기 쉬운 것일 수 있습니다.