- Home /
Constrain Generic to Specific Classes
If I have a function
T Function <T> (T script) where T: ??? { }
How do I constrain T to specific classes, such as accepting SpriteRenderers and Images?
I'm probably misunderstanding generics, is there another way to constrain a parameter of a function to multiple classes?
Answer by mchts · May 24, 2019 at 01:23 PM
You could do sth like :
T Function<T, U, V>(T script) where T : V, U { }
but T should have been derived from U and V... so this couldn't be considered as useful. There is a more straightforward way of doing what you want. And it's overloading method as you need:
SpriteRenderer Function (SpriteRenderer script){ }
Image Function (Image script){ }
etc.
I don't really get the first one, but you said it won't help, so I guess it doesn't really matter.
I could do the second one, but there'll have to be different names for each one, so...
Also, I came up with an idea, but I have no idea if it would work:
T Function <T> (T script) {
if(typeof(script) == SpriteRenderer) {
SpriteRenderer script = script as SpriteRenderer;
}
else print("Not acceptable type");
}
It will work with a little workaround:
T Function <T> (T script) {
if(typeof(T) == typeof(SpriteRenderer)) {
SpriteRenderer script = script as SpriteRenderer;
}
else print("Not acceptable type");
}
but it is not best practice. When it comes to the second solution your function name won't change but you will have multiple options with same method name and you will also able to restrict the types you want to use. Do not hesitate using overload methods. But again you could go with your approach.
And when it comes to @ShadyProductions 's solution it will also work but your method will accept any type that derives from Component base class. You could use this approach too unless you want to restrict your types with specific ones.
Oh never$$anonymous$$d, I misinterpreted overloading methods, I thought the return type has to be different, not the parameters.
The second method would work then, thank you.
Answer by Bunny83 · May 24, 2019 at 11:00 PM
Generics are a bit tricky. You can use any type as constraint. However the types allowed would be the class specified in the constraint or any derived class. Note that multiple generic constraints are not combined with "or" but with "and". So all constraints you put on a type parameter have to be fulfilled at the same time. So it's not possible to specify two different types as constraints since a a type can't be a SpriteRenderer and MeshRenderer at the same time.
Note that generics are fully compiled at compiletime. So the code inside a generic method need to work with all types you are allowed to pass in as type parameter. A generic method without any constraints can't do much since there's almost no common ground. By applying constraints to the type parameter you essentially set up a "contract" so the compiler knows whatever type will be used will have these specifed things. The actual type binding is done dynamically at runtime. That's why the code need to compile with all acceptable types.
Your usecase isn't quite clear. If you just want to prevent a method from being fed a wrong type this can only be done with runtime checks unless the types you want to use have a a common basclass
So is using generics not really suitable for this?
I'm making a function that changes the color value of a component script, and Image, Text, SpriteRenderer, etc. all have a color variable.
Exactly, generics aren't suitable for this since just having a equally named property doesn't make the components related in the sense of OOP or inheritance. If two or classes do not have a base class or interface in common you can't treat them in a generic or abstracted way since there's no abstraction.
Answer by ShadyProductions · May 24, 2019 at 06:58 PM
You can restrict T to a base class of a given type.
I believe most have Component as base class you could do where T : Component
Ok, thank you. Is there any way to go even more specific with that?
Your answer
Follow this Question
Related Questions
MonoBehaviour pseudo-singleton with C# generics 1 Answer
2 problems with serialization of a generic list of a custom class 3 Answers
(analytics beta) How to initialize Generic Dictionary from JS? 1 Answer
Big problem with a small singleton 1 Answer
Is the class derived/inherited from generic list serializable? 1 Answer