문제

대답하는 동안 작은 구조물을 걷어차 고 이 게시물, 나는 예기치 않게 다음을 발견했다.

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 추가로 업데이트되었습니다.

구조물 생성자에서 속성을 초기화하려고 할 때이 오류가 표시되면 솔루션은 생성자 매개 변수를 변경하여 속성 자체 대신 백킹 필드를 지정하는 것입니다. 자동 구현 된 특성은 백업 필드가 없으므로 생성자로부터 어떤 식 으로든 초기화 할 수 없기 때문에 스트러크에서 피해야합니다.

따라서 공식적인 지침은이 문제에 빠질 때 구조 스타일 속성을 사용하는 것임을 의미합니다. 이는 지금까지 탐색 한 다른 두 대안 중 하나보다 덜 모호하고 더 읽기 쉬운 것일 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top