2012-08-22 3 views
0
public class ModelInfo 
{ 
    public int AssignedCount { get; set; } 
    public int UnassignedCount { get; set; } 
    public int TotalCount { get { return UnassignedCount + TotalCount; } } 
} 

를 일으키는 * 편집 : 나는 그래서 TOTALCOUNT 속성은 UnassignedCount +를 TOTALCOUNT를 추가 점에서이 코드를 넣을 때 실현 * (나는 다른 두 수를 추가하는 의미 함께). 누군가가 SO 오류가 발생하는 이유에 대한 충분한 설명을 제공해 주시겠습니까? 내 말은, 낮은 수준의 것들.C 번호 - 속성에 유래

Stackoverflowing!

+3

스택 오버플로가 발생하는 이유를 알고 싶습니까? 무한 재귀가 답입니다. 'TotalCount'는 "TotalCount"를 호출합니다. "TotalCount"는 ... 당신에게 아이디어를줍니다. –

답변

13

TotalCountTotalCount에서 호출하고 있습니다. 그렇게하지 마십시오.

속성 값 대신 다른 필드를 사용할 수 있습니다.

비록, 당신의 코드로 읽어야 의심 :

public int TotalCount { get { return UnassignedCount + AssignedCount ; } } 

편집 : 당신이 속성을 사용하는 경우, .NET 컴파일러 실제로이 개 기능을 생성하기 때문에 유래가 발생하는 이유에 대한 같은 , 그것은이다 , set_PropertyNameget_PropertyName. 따라서 본질적으로 무한히 깊어지는 get_PropertyName 메서드 호출에서 스택 오버 플로우가 발생합니다.

0

TotalCount 게터 내에서 TotalCount을 참조하고 있기 때문에. 무한 루프는 스택 오버 플로우에 도달 할 때까지 발생합니다.

0

당신은 라운드 루핑 및 라운드 그래서 대략 TotalCount

에 대한 값을 얻으려고, TOTALCOUNT를 얻기위한 논리는 다음과 같습니다 TOTALCOUNT에 대한 UnassignedCount

  • 가져 오기 값

    • 가져 오기 값

    반복하고, 헹구고 씻으십시오.

    편집 : Wiki 당신은 무한 재귀에

  • 0

    자체를 요구하는 속성이 이유의 경우와 호출 스택은 (이론적으로) 무한히 깊은 얻을 것 때문입니다. 그리고 필요한 모든 데이터를 유지할 수있는 무한한 스택이 없습니다.

    1

    중첩 호출을 추적하는 데 사용되는 "스택"이라는 메커니즘이 있습니다. 메서드 나 함수를 호출하면 현재 "스택 프레임"(호출 한 메서드가 반환 될 때 컨트롤이 전송하는 주소와 메서드의 매개 변수 및 메서드 locals)이 스택에 푸시됩니다. 컨트롤이 메서드로 돌아 가면이 스택 프레임이 꺼지고 CPU 레지스터가 이전 상태로 복원되므로 메서드가 계속 실행될 수 있습니다.

    스택 메모리의 고정 할당은, 그리고 당신이 당신의 기능이 때 CPU 레지스터의 상태를 복원하는 데 필요한 정보를 저장하는 장소에서 실행하기 전에 그러므로 당신은 단지 깊은 많은 수준을 호출 할 수 있습니다 돌아왔다. 이 시점에서 스택 오버플로 오류가 발생합니다. 스택 오버플로가 발생했기 때문입니다. 너무 많은 중첩 된 호출을 작성하여 메모리가 부족하여 기록 할 수 없습니다.

    그래서 예외가 발생합니다. 무한히 반복됩니다 : 스택에 더 이상의 공간이 없을 때까지 속성 getter가 반복적으로 스스로를 호출합니다.

    3

    누군가가 SO 오류가 발생하는 이유에 대해 자세히 설명해 주실 수 있습니까?

    물론이 : TotalCount를 계산하기 위해, 컴파일러는이 같은 코드 생성

    • UnassignedCount
    • TotalCount
    • 는 반환에게 TotalCount
    • 에 결과를 UnassignedCount 추가 가져 오기

    TotalCount의 getter 속성을 호출 할 때 (getter는 특별한 구문을 사용하는 일반 인자없는 함수이므로) 런타임은 반환 주소를 스택에 배치합니다. 두 번째 단계는 스택에 하나의 추가 반환 주소를 사용하여 처음부터 다시 찾는다. 세 번째 단계는 그것을 다시하고, 네 번째, 다섯 번째 등을 반복합니다. 각 호출은 스택에 다른 리턴 주소를 보관합니다. 이것은 스택의 한계까지 계속 이어지고, 그 시점에서 예외가 발생합니다.

    4

    (IMO) 무슨 일이 일어나고 있는지 볼 수있는 가장 쉬운 방법은 방법으로 이러한 속성을 변환하는 것입니다

    // If we didn't have properties, this is what the two first lines would be. Ick! 
    private int assignedCount; 
    private int unassignedCount; 
    
    public int GetAssignedCount() 
    { 
        return assignedCount; 
    } 
    
    public void SetAssignedCount(int value) 
    { 
        assignedCount = value; 
    } 
    
    public int GetUnassignedCount() 
    { 
        return unassignedCount; 
    } 
    
    public void SetUnassignedCount(int value) 
    { 
        unssignedCount = value; 
    } 
    
    // And here's the read-only TotalCount property translation 
    public int GetTotalCount() 
    { 
        return GetUnassignedCount() + GetTotalCount(); 
    } 
    

    지금 GetTotalCount() 내에서 재귀 정말 명확해야한다. 메서드는 무조건적으로 자신을 호출하므로 결국 스택을 폭파시킵니다.

    자동 구현 속성의 혼합물과 재산 필드와 같은 가끔 액세스가 변장 단지 방법 정말 걸 기억의 방해가 모습을 액세스하는 사실

    . 위의 번역을 보면 더 명확 해집니다.

    2

    다음과 같이 작성할 수 있습니다. TotalCount를 절대로 값을 설정할 수 없으므로주의해야합니다. 아마도 이것을 의미할까요?

    public class ModelInfo 
    { 
        public int AssignedCount { get; set; } 
        public int UnassignedCount { get; set; } 
        public int TotalCount { get { return UnassignedCount + AssignedCount; } } 
    }