Checking types for multiple components on a gameobject

I’m wondering if there is an easy way to detect what components are attached to a gameobject. I have many subclass components that each have different dependencies, each component has a “on” and “off” state that allows it to perform its behaviour. The component can only perform its behaviour if the gameobject has the other components attached as it requires them to do so. Think of a car needing an engine to move, but to fit an engine it might also require wheels, or a steering wheel etc.

What happens at the moment is when the command is given (by script, or player) to turn that component “on” it goes through a check list to see if all the dependencies are met and the component can be turned “on”. I need a way to declare the dependencies and check that they are met.

Here is how I tried to tackle it:

Using a list of the superclass component type, I added each type of component as a dependency. The main problem I am having is checking that type on the gameobject.

So on the component in question I would add this, probably in start or awake:

this.AddComponentDependency(*COMPONENT-TYPE-GOES-HERE*);

Then before the component is turned “on” I’d call the checking method which returns true or false:

CheckComponentDependencies();

Which looks like:

	private bool CheckComponentDependencies()
	{
		SpaceComponent[] _components = gameObject.GetComponents<SpaceComponent>();
		List<SpaceComponent> _componentList = _components.ToList();
		
		for(int cntr = 0; cntr < _componentList.Count; cntr++)
		{
			// Do some type checking here
			
			
			/*
				if( _componentDependencies.Contains( * THE NON-CAST TYPE AT THE INDEX IN _componentList * e.g. _componentList[cntr].GetType() ) 
				{
					return true;
				}
			*/
			// HOW TO DO THIS?

		}
		
		return false;
	}

I can do it this way, but I’m trying to avoid having to declare the type when I call the method and it also means I have to write code for each dependency:

	private bool CheckComponentDependencies<T>()
	{
		SpaceComponent[] _components = gameObject.GetComponents<SpaceComponent>();
		List<SpaceComponent> _componentList = _components.ToList();
		
		T comp = _componentList.OfType<T>().FirstOrDefault();
		
		if(comp != null)
		{
			return true;
		}
		else
		{
			return false;
		}
	}

I asked the question a different way on SO and got an answer.

Copied From Answer

Basicly you should get all the types from collections using Linq and then compair the result.

var toolsAvailableTypes = toolsAvailable.Select(t => t.GetType()).Distinct();
var toolsRequiredTypes = toolsRequired.Select(t => t.GetType()).Distinct();
if (toolsRequiredTypes.Except(toolsAvailableTypes).Any()) {
    //building 
}

It is not clear, should you compair only types of instruments or quantity also. My answer assume you don’t care about quantity and you can build with one spanner when you require two.

-Update

To comply the requirement about subclasses (Sriram Sakthivel mentioned it) you can check if available tool type is subclass to required tool type so you can use any SpecialSpanner when you need a Spanner.

var toolsAvailableTypes = toolsAvailable.Select(t => t.GetType()).Distinct().ToList();
var toolsRequiredTypes = toolsRequired.Select(t => t.GetType()).Distinct().ToList();

if (CanBuild(toolsAvailableTypes, toolsRequiredTypes)) {
    Console.WriteLine("building"); } else {
    Console.WriteLine("not enough minerals");
}

CanBuild method:

bool CanBuild(List<Type> toolsAvailableTypes, List<Type> toolsRequiredTypes) {
    foreach (var requiredType in toolsRequiredTypes)
    {
        bool isAvailable = toolsAvailableTypes.Any(availableType => availableType.IsSubclassOf(requiredType) || availableType == requiredType);
        if (!isAvailable)
        {
            return false;
        }
    }
    return true; 
}

Link To Question