# Null 레퍼런스

> Understand what causes a NullReferenceException in C# and how to avoid uninitialized object references.

C#의 `NullReferenceException`은 값이 `null`인 유형의 멤버에 액세스하려고 할 때 발생합니다. 런타임 시 `NullReferenceException`이 발생하는 경우 오브젝트 레퍼런스 변수를 사용하기 전에 초기화하는 것을 잊어버린 경우가 많습니다. null 레퍼런스를 생성하는 일반적인 코딩 오류에 대한 전체 설명은 [Microsoft 기술 자료](https://learn.microsoft.com/en-us/dotnet/api/system.nullreferenceexception?view=net-8.0)를 참조하십시오.

null 레퍼런스 오류 메시지는 다음과 같습니다.

```
NullReferenceException: Object reference not set to an instance of an object
    at Example.Start () [0x0000b] in /Unity/projects/nre/Assets/Example.cs:10 
```

이 오류 메시지는 스크립트 파일 `Example.cs`의 10번째 줄에서 `NullReferenceException`이 발생했으며, `Start()` 함수 내에서 예외가 발생했음을 나타냅니다. 이렇게 하면 Null 레퍼런스 예외를 쉽게 찾고 수정할 수 있습니다. 이 예제에서 코드는 다음과 같습니다.

```lang-csharp
using UnityEngine;
using System.Collections;

public class Example : MonoBehaviour {

    // Use this for initialization
	void Start () {
		GameObject myGameObject = GameObject.Find("exampleGameObject");
    	Debug.Log(myGameObject.name);
    }
	
}
```

코드는 ‘exampleGameObject’라는 게임 오브젝트를 찾습니다. 이 예제에는 해당 이름의 게임 오브젝트가 없으므로 `Find()` 함수는 `null`을 반환합니다. 다음 줄(9번째 줄)에서 스크립트는 `myGameObject` 변수를 사용하여 참조하는 게임 오브젝트의 이름을 출력합니다. 존재하지 않는 게임 오브젝트에 액세스하려고 하기 때문에 Unity는 `NullReferenceException`을 반환합니다.

## Null checks

이 예제의 솔루션은 특정 이름의 게임 오브젝트가 존재하지 않는 상황에 대한 결과를 포함하는 것입니다. 다음 스크립트는 `go` 변수가 `null`을 반환하는지 확인하고, 그렇다면 메시지를 표시합니다.

```lang-csharp
using UnityEngine;
using System.Collections;

public class Example : MonoBehaviour {

    void Start () {
	    GameObject myGameObject = GameObject.Find("exampleGameObject");
		if (myGameObject == null) {
			Debug.Log("No GameObject called exampleGameObject found");
    	} else {
			Debug.Log(myGameObject.name);
    	}
    }
    	
}
```

### 커스텀 == 연산자

[UnityEngine.Object](/engine/6000.0/manual/scripting/get-started/fundamental-unity-types/class-object.md)에서 상속하는 유형의 경우 Unity는 C# [같음 및 같지 않음 연산자](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/equality-operators)의 커스텀 버전을 사용합니다. 즉, 이전 예제(`myGameObject == null`)의 null 체크는 `myGameObject`가 기술적으로 유효한 C# 오브젝트 레퍼런스를 보유하고 있더라도 `true`를 평가(및 반대로 `myGameObject != null`이 `false`를 평가)할 수 있습니다. 이는 다음 두 가지 경우에 발생합니다.

1. 해당 오브젝트는 Unity가 에디터에서 초기화되지 않은 MonoBehaviour 필드를 채우기 위해서만 사용하는 ‘fake null’ 또는 플레이스홀더 오브젝트일 수 있습니다. 이러한 오브젝트는 참조하려는 경우 이러한 필드의 소스를 찾는 데 도움이 되는 유용한 디버깅 정보를 저장합니다.
2. 오브젝트는 아직 가비지 컬렉션이 이루어지지 않은 관리되는(C#) 오브젝트일 수 있지만 관리되지 않는(C++) 상대 오브젝트가 삭제되었기 때문에 null로 간주되어야 합니다.

## Try/Catch 블록

**Inspector** 창에서 초기화해야 하는 변수를 사용하는 경우에도 Unity는 `NullReferenceException`을 호출합니다. 이 작업을 잊으면 변수는 `null`이 됩니다. `NullReferenceException`을 다루는 다른 방법은 `try`/`catch` 블록을 사용하는 것입니다. 예시:

```lang-csharp
using UnityEngine;
using System;
using System.Collections;

public class Example2 : MonoBehaviour {

    public Light myLight; // set in the inspector
	
	void Start () {
		try {
			myLight.color = Color.yellow;
    	}		
    	catch (NullReferenceException ex) {
	    	Debug.Log("myLight was not set in the inspector");
		}
	}
	
}
```

이 코드 예제에서 `myLight`라는 변수는 인스펙터 창에서 설정해야 하는 `Light`입니다. 이 변수가 설정되지 않으면 기본값은 `null`입니다.

`try` 블록의 광원 컬러를 변경하려고 하면 `NullReferenceException`이 발생합니다. 이 경우, `catch` 블록 코드에 인스펙터에서 광원을 설정하라는 메시지가 표시됩니다.

## 추가 리소스

* [UnityEngine.Object](/engine/6000.0/manual/scripting/get-started/fundamental-unity-types/class-object.md)
