I tried to make my example as concise as possible, but it’s still a little long. Apologies.
I have a standard delegate pattern,
but sometimes the class instance the delegate belongs to may have been destroyed when i go to call the delegate.
So, i check myDelegate.Target == null
, but the check always evaluates an not-equal. But if the delegate itself prints out the value of this
, the result is “null”.
So, i started checking if myDelegate.Target.ToString()
is the string “null”, and that check behaves as expected. What am i missing here ? Is this a C# weirdness or a Unity weirdness ?
Here’s a script demonstrating the issue.
using UnityEngine;
using System.Collections;
// The console output of this program is this:
//
// nullMethod1: False nullMethod2: False
// Calling in method 1
// You called me! this = New Game Object (LittleGuy)
// Calling in method 2
// You called me! this = New Game Object (LittleGuy)
// doing careful delegate callback after the GameObject the delegate belonged to has been destroyed..
// nullMethod1: False nullMethod2: True
// Calling in method 1
// You called me! this = null
public class LittleGuy : MonoBehaviour {
public void callMe() {
Debug.Log("You called me! this = " + this.ToString());
}
}
public class delegateTargetTest : MonoBehaviour {
public delegate void SimpleDelegate();
public SimpleDelegate myDelegate;
public void Start() {
GameObject go = new GameObject();
LittleGuy lg = go.AddComponent<LittleGuy>();
StartCoroutine(beginTest(lg.callMe));
GameObject.Destroy(go);
}
private IEnumerator beginTest(SimpleDelegate dtt) {
Debug.Log("doing careful delegate callback while everything is fine..");
tryCallDelegate(dtt);
// give the GameObject time to be destroyed.
yield return new WaitForSeconds(0.5f);
Debug.Log("doing careful delegate callback after the GameObject the delegate belonged to has been destroyed..");
tryCallDelegate(dtt);
}
void tryCallDelegate(SimpleDelegate dtt) {
bool nullTestMethod1 = (dtt.Target == null);
bool nullTestMethod2 = string.Equals(dtt.Target.ToString(), "null");
Debug.Log("nullMethod1: " + nullTestMethod1 + " nullMethod2: " + nullTestMethod2);
if (!nullTestMethod1) {
Debug.Log("Calling in method 1");
dtt();
}
if (!nullTestMethod2) {
Debug.Log("Calling in method 2");
dtt();
}
}
}