Well, i guess your method definition looks like this:
public static bool HasComponent<T> (this GameObject obj)
{
return obj.GetComponent<T>() != null;
}
in which case you run into a nasty edge case problem. In the past this definition wouldn’t compile since GetComponent used to have a contraint on the generic parameter to only allow types derived from Component.
Unity seem to have changed the definition and removed the constraint. This allows us to also use interfaces which is great.
However in your case the problem (which only occurs in the editor btw) is, that the “!=” check in your generic method most likely does a “System.Object” comparison. When testing inside the editor GetComponent will always return an instance. However that instance usually pretends to be null. This is done by overloading the “UnityEngine.Object” “==” and “!=” operators. Since your generic method doesn’t use that specific operator it actually sees that fake-null object which of course is not null.
The problem shouldn’t occur in a built version of your game.
There are several ways to make it work inside the editor as well:
First, add a constraint to “Component”:
public static bool HasComponent<T> (this GameObject obj) where T : Component
{
return obj.GetComponent<T>() != null;
}
this will make the generic method to use the overloaded operators. However doing so prevents you from using interfaces with your method.
Another way would be to simply do an “as-cast” to ensure the right type:
public static bool HasComponent<T> (this GameObject obj)
{
return (obj.GetComponent<T>() as Component) != null;
}
This should work with all cases.
Another one would be
public static bool HasComponent<T> (this GameObject obj)
{
return obj.GetComponent(typeof(T)) != null;
}
The System.Type version of GetComponent always returns a Component. Since you don’t use the actual type it’s not necessary to use the generic version.