menu_bookDocumentation

IsValid Pattern: Safe Null and Destroyed Object Checks

calendar_today May 20, 2026 schedule ~1 min read person PatrickJr verified 50

Destroying a GameObject or Component doesn't erase the C# reference — the variable still holds a non-null but dead object. A plain != null check will pass on destroyed objects, leading to exceptions or silent failures.

The Problem

CSHARP
// ❌ Wrong — reference is still non-null after Destroy()
if ( myObject != null )
{
    myObject.DoSomething(); // might throw or do nothing
}

// ✅ Correct — safe even if myObject is null
if ( myObject.IsValid() )
{
    myObject.DoSomething();
}
IsValid() handles both null references AND destroyed objects in a single check.

Common Patterns

Guard before use:

CSHARP
protected override void OnUpdate()
{
    if ( !_target.IsValid() ) return;
    var dist = WorldPosition.Distance( _target.WorldPosition );
}

Filter destroyed objects from lists:

CSHARP
_targets.RemoveAll( t => !t.IsValid() );

Guard async callbacks (objects may be destroyed during await):

CSHARP
async Task ShootAfterDelay()
{
    await Task.DelaySeconds( 1.0f );
    if ( !this.IsValid() ) return; // component might be destroyed
    FireProjectile();
}
this.IsValid() works on your own components — essential for guarding any code after an await, timer, or callback where the object's lifetime is uncertain.
Was this helpful?