Changing Type in a method

I have created this sample code below.

Now let’s say I am using this in a switch statement to do the EXACT same thing in every case, except for the type. The type is changed to say… HealthPotion, or StrengthPotion, DefensePotion… So on.

Is there a clean way to change this so that I can pass in some type of variable as a type, and turn this into a reusable method instead of having such similar code repeated? Or is this one of those situations where repeated code is just unavoidable?

Thanks in advance!!

Generics!

Just name your method something like this:

void Method<T>(T component) where T : Component

Then replace the types with T

1 Like

Just sounds like you want to have a common base type of interface for these different types so that you only need to GetComponent<T> for this common type.

Also, you had posted this in the general discussion section. I’ve edited the post to be in the correct section.

EDIT: The above post makes more sense reading the code again.

1 Like

Something like this might be helpful??

A generic switch statement, which checks for script type, but passes the same variables to each script??

Cheers!

public class ScriptCaller : MonoBehaviour
{
    public void CallScript(MonoBehaviour script, float var1, float var2, float var3)
    {
        switch (script)
        {
            case Script1 script1:
                script1.ProcessFloats(var1, var2, var3);
                break;
            case Script2 script2:
                script2.ProcessFloats(var1, var2, var3);
                break;
            default:
                Debug.LogError("Unknown script type.");
                break;
        }
    }
}

public class Script1 : MonoBehaviour
{
    public void ProcessFloats(float var1, float var2, float var3)
    {
        // Implementation specific to Script1
        Debug.Log("Script1: " + var1 + ", " + var2 + ", " + var3);
    }
}

public class Script2 : MonoBehaviour
{
    public void ProcessFloats(float var1, float var2, float var3)
    {
        // Implementation specific to Script2
        Debug.Log("Script2: " + var1 + ", " + var2 + ", " + var3);
    }
}

That’s also a bit of an anti-pattern that won’t scale with time, and is just more repeated code. Whereas common base class removes the need for the switch statement entirely.

1 Like

Exactly. Instead of a common base class you could also use interfaces which are usually more flexible and do not create “inheritance hell”. Though for something like potions a common base class would still make sense. Especially when certain property and functions are really the same for all potions. GetComponent(s) does work with the base classes or interface types as well.

Interfaces would be better when only some potions may have / need a certain property. So only those potions would implement that interface.

public interface IVFXHolder
{
    YourVFXType GetVFX();
    void SetVFX(YourVFXType aNewVFX);
}

Of course such an interface essentially represent some kind of sub type or “trait” that the class implements.

1 Like

That wouldn’t work unless you have inheritance or interfaces in place that you can use in your generic constraints. Generic code has to work with ALL potential types. An unconstraint type argument (or just contraint to Component) can not use any type specific methods or properties. I’m also not sure how a generic method would help with the problem at hand. Just plain inheritance would be enough.

As I said a couple of times, generics are somewhat the opposite of polymorphism. Inheritance represents a common ancestor that every sub class inherits. So every subtype IS also of the same type as the ancestor. With polymorphism you inherit all the data / fields from your ancestor but you can override methods / functionality.

Generics on the other hand do the opposite. They actually create distinct separate types but create common functionality that works on different data, as long as the constraints allow it. A List<int> and a List<string> have the same functionality, but are completely incompatible with each other. They do not have a common ancestor and can not be treated the same way. You need distinctly different code to use them. With generics covariance and contravariance can be a thing, but not for List as the data flow direction has to be one way. A List can read and write so that’s out of the question.

1 Like

Oh yeah I didn’t realize he was using custom methods for his classes. Yeah in this case the different types need to share a parent class or an interface.