Try-catch alternative


I made a script to constantly change the color of a Sprite.
Then I decided to also constantly change the color of a Panel on my GUI.

So, in the one case there is a SpriteRenderer, in the seccond case there is an Image instead.

My thoughts: I try to assign a SpriteRenderer to a variable, if I can’t do that it means the script is running inside a Panel, then I get an Image.

I changed the code to work on both, a Sprite and a Panel.

I tried this:

try {
			spriteRenderer = GetComponent<SpriteRenderer> ();
			isSprite = true;
			isSprite = false;
			img = GetComponent<Image>();

For no effect. Actually, it showed me a message error telling me my Panel has no SpriteRenderer.

Then I tried this:

if(spriteRenderer = GetComponent<SpriteRenderer> ()){
			isSprite = true;
		} else {
			isSprite = false;
			img = GetComponent<Image>();

Which works exactly like I expected the try-catch would.

My question: WHY?

Isn’t the try-catch supposed to be used in cases like this?

try / catch is to catch exceptions thrown by methods. It doesn’t work here because GetComponent doesn’t throw any. Instead when a component is not found it returns null. Putting a component variable in an if statement checks whether the variable exists (is non-null).

If you want to use exceptions you can use an intermediary method.

T GetComponentWithException<T>() where T : Component
  var c = GetComponent<T>();
  if (c)
    return c;
  throw new ArgumentException(typeof(T).Name + " could not be found.");

The line:

  if(spriteRenderer = GetComponent<SpriteRenderer> ()){

is an assignment statement ‘=’, not an equality check ‘==’.
However, C# will check the result of the assignment if it can be converted to a boolean, which UnityObject can be. If they couldn’t become a bool value, then the code would not compile. UnityObjects can’t actually be null, they have a special value that is returned in place of null for any ‘null’ reference to a UnityObject returned by one of Unity’s built-in functions like GetComponent.

The code you have works because the fake ‘null’ UnityObject converts to ‘false’, and any real UnityObject converts to true.

As an aside, you might want to get more familiar with the C# language to understand these kinds of werid things. Unity does some werid things, and I remember a blogpost about this werid behaviour with nulls and bools a few months back.