2011-08-20 2 views
0

다음과 같은 코드가 있습니다.내 코드가 true if-condition을 무시하는 이유는 무엇입니까?

 private static void checkCodesInPlayerCenter(GameObject player) 
    { 
     Vector2 collisionCenter = player.GetCollisionCenter(player.PublicCollisionRectangle); 

     if (TileMap.GetMapSquareAtPixel(collisionCenter) == null) 
     { 
      return; 
     } 

     for (int i = 0; i < TileMap.GetMapSquareAtPixel(collisionCenter).Codes.Count; ++i) 

때때로 GetMapSquareAtPixel에서 가져 오는 객체가 null 일 수 있습니다. for 루프에서 NullReferenceException을 발생시키지 않으려면 null인지 확인하고 일찍 함수를 끝내면 반환 된 객체가 null 인 경우에도 if 조건을 완전히 무시한 것처럼 보입니다. return 문에 중단 점을 설정했지만 코드가 절대 이동하지 않고 대신 NullReferenceException을 트리거합니다.

어떤 도움을 주시겠습니까?

+0

아마도 'TileMap'이 null입니다. 혹시? 아니면'코드'? 아니면 '선수'? –

+1

null 인 collisionCenter 일 수 있습니까? – darma

+0

메서드 내부의 첫 번째 줄이 호출 될 때 어떤 결과가 나타 났습니까? – saber

답변

2
그것은

TileMap.GetMapSquareAtPixel(collisionCenter) 

가 null가 아닌 가능성의

하지만

TileMap.GetMapSquareAtPixel(collisionCenter).Codes 

이다. 그럴 경우

TileMap.GetMapSquareAtPixel(collisionCenter).Codes.Count 

은 NullReferenceException과 함께 실패합니다.

당신은 조건 당신의 가드에 그를 추가해야합니다 : 함수가 (가능성이 개 다른 결과를 반환

if (TileMap.GetMapSquareAtPixel(collisionCenter) == null || 
     TileMap.GetMapSquareAtPixel(collisionCenter).Codes == null) 
    { 
     return; 
    } 
+0

이 @ anthony-sottile의 솔루션이 올바른 것입니다. 기본적으로 첫 번째 호출 (검사 할 때)은 null을 반환하지 않습니다. (실제로 그렇듯이) 실제로는 코드 목록의 요소가 변경되었지만 제거한 후에 더 이상 요소가 없으면 목록이 자동으로 null이된다는 것을 알지 못했습니다. 마지막 하나. 그래서 실제로 마지막 코드가 제거 된 후에 루프 중에 NRE를 트리거했습니다. (항상 제거되는 것은 아닙니다) 도움 주셔서 감사합니다. – xNidhogg

1

어떤 경우 만 두 번 어쨌든이 가능한 고가의 함수를 호출하지 않습니다 - 변수에 결과를 저장하고 이 변수를 체크/사용하십시오.)

.Codes 부분이 null 인 경우 - 이것도 확인하십시오!

0

함수의 반환 값이 두 조건간에 변경 될 수 있습니까?

시도 지역 변수에 할당하고 확인을하고 (그리고 디버거를 통해 단계)을 GetMapSquareAtPixel 호출이 호출 대 (한 통화가 비싼 경우

private static void checkCodesInPlayerCenter(GameObject player) 
{ 
    Vector2 collisionCenter = player.GetCollisionCenter(player.PublicCollisionRectangle); 

    var squareAtPixel = TileMap.GetMapSquareAtPixel(collisionCenter); 

    if (squareAtPixel == null) 
    { 
     return; 
    } 

    for (int i = 0; i < squareAtPixel.Codes.Count; ++i) 

이 또한 가능성이 더 나은 경우 모두 당신이 정말로 신경이 걱정이다.)

EDIT : NRE가 던져 지려고 시도한 변수는 무엇입니까?

0

로컬 변수에 TileMap.GetMapSquareAtPixel 반환 값을 할당하고 null 조건을 검사 한 후 for 루프에 같은 var를 사용하는 것이 좋습니다.

이렇게하면됩니다.

0

전화하는 방법이 변이 상태 (일반적으로 게터 이 아니어야 함) 인 경우에는 멱등 한 호출이 아니므로 두 번 이상 호출해도 안전하지 않을 수 있습니다.

또한 디버거에서이 표현식을 추가하면 코드를 실행하기 전에 NEF가 발생하기 전에 평가할 가능성이 큽니다.

TileMap.GetMapSquareAtPixel 값을 별도의 변수에 저장하려고합니다.

관련 문제