There is actually one condition that could cause this race condtion, and that is if the SavingWrapper is calling FadeOutImmediate() in Awake() instead of Start() (Because if SavingWrapper gets it’s Awake() done before Fader does, then CanvasGroup won’t be set properly.
In any event, null checking is, short of a quick and dirty Lazy, an ideal solution.
Bonus: Quick and dirty Lazy evaluation:
CanvasGroup _canvasGroup; //Do not refer to this in code
CanvasGroup canvasGroup //Always refer to this one
{
get
{
if(_canvasGroup==null) _canvasGroup = GetComponent<CanvasGroup>();
return _canvasGroup;
}
}
With this setup, you effectively prevent any possible race condition, as any call to canvasGroup ensures that the backing field _canvasGroup will exist before the canvasGroup property is completely evaluated. With this, you can take both checks out, both in Awake() and FadeOutImmediate. (In fact, you’ll have to, they won’t compile as canvasGroup cannot be set outside of the property itself).