#how important are generics?

1 messages · Page 1 of 1 (latest)

atomic sapphire
#

and i dont mean predefined functions like Lists or dictionaries or get component, i mean making your own generics and implementing them into systems

hexed sigil
#

Always ways around generics

fresh grail
#

understanding them is pretty crucial in general when working with stuff, imo.

it's a useful tool, but it's not a universal tool. don't stuff it where it doesn't belong

atomic sapphire
#

cause im kinda intermediate in unity and when it comes to coding/c# experitse i thought i was kinda solid, i used composition and oop and knew abt several techniques like state machines using enums, when to use inheritance and when to use composition, but generics im trying to learn them and i js cant grasp when ill use them

fresh grail
#

how important it is to write them depends entirely on the systems you make

atomic sapphire
#

like im at a point where i can kinda see their power/usefulness but i js dont see a situation where ill use them ykwim

fresh grail
#

think of all the times you've used generics in those "predefined" functions

#

someone wrote those

atomic sapphire
#

like what kind of problem do i need to encounter to say "yeah generics fix this instantly"

fresh grail
#

if you need to write something like those, you'd need to write generics

atomic sapphire
#

without having composition or enums or polymorphism js do that

fresh grail
atomic sapphire
fresh grail
#

there's no problem you'd encounter where you'd say "yeah structs fix this instantly"

atomic sapphire
#

fair

fresh grail
#

or "yeah namespaces fix this instantly"

#

same thing here

#

this is just a tool in your toolbelt to make good systems/interfaces (in the sense of usage surface, not actual interfaces)

atomic sapphire
#

like what

fresh grail
hexed sigil
#

I use them in game dev for instance:

SpellSO //abstract
SpellProjectileSO : SpellSO
SpellAreaSO : SpellSO

Spell<T>: where T: SpellSO //abstract
SpellProjectile : SpellSO<SpellProjectileSO>
SpellArea : SpellSO<SpellAreaSO>

But this is with constraints

fresh grail
#

unity events

atomic sapphire
#

i see

atomic sapphire
#

but dont u lose the benefits of classes? like now SpellProjectileSO doesnt really have an identity, its js a Spell<T>

#

what if u have behaviour thats different for SpellArea like time active or smth?

hexed sigil
#

Yeah so each derived class also wants a specific data (prevents casting too) which I add as a constraint. This helps extend the polymorphism too

atomic sapphire
#

theres no individualization

fresh grail
#

generics work alongside the rest of the type system, not against it

atomic sapphire
#

ah

#

i see

atomic sapphire
hexed sigil
#

problem with generics is you can't really serialize them with unity unless you do have constraints

atomic sapphire
#

like id have a base weaponSO and then a SworsSO thatd have things like swordthickness and whatnot thatd also inheir from weaponSO

#

and then after equipping the weapon id have to case the weaponSO to make it a swordSO to get its values

sacred cloud
atomic sapphire
atomic sapphire
hexed sigil
#

Depends, usually you do want to be able to construct stuff on the editor if possible

#

prefabs, ect. But you can also do it in awake

atomic sapphire
#

yeah i see that happening

hexed sigil
#

Generics for the most part reduce type checking similar to what chris said

atomic sapphire
#

yeah i just havent really internalized their use cases yet ngl

hexed sigil
#

like you can make an inventory system with a bunch of inventory slot types using generics, or just make a bunch of slot classes and type check them

sacred cloud
atomic sapphire
#

they js seem weird to me

sacred cloud
#

Its not something you'll use frequently

#

It really boils down to a case where you want to store a value, but dont necessarily care what that value is

atomic sapphire
#

yeah an inventory system would be great for that

fresh grail
atomic sapphire
#

aight appreciate yall for the help

hexed sigil
atomic sapphire
#

like it might actually be a good system but i wouldnt have that grasped in my mind yet

#

ive dealt with classes and all their techniques basically since ive started so my mind is kinda hardcoded to thinking in that sphere

#

so when u show this to me im kinda js instinctively thinking "why dont i js use an abstract class as an identifier AND to hold base values ANY spell type would have?"

#

ik ur system is prob better but i js dont know how yet

#

i wont get it by talking abt it thats for sure ill have to encounter situations and such and go practical but still appreciate the help

hexed sigil
#

Without the generics you could only declare the base SO type, but then you'd have to cast it inside of the class. Not that big of a deal but it's less of a strong typing if you do it that way.

#

But adding the generic constraint, you're saying that the declaration of the SO does have a strong type when extending the class with it.

#

But if you're coming from js it's probably not a big deal ;p

atomic sapphire
#

what im kinda confused here

#

in ur code

#

is the above part a different case and scenario than the below part?

atomic sapphire
#

ur showing the different case scenarios right?

hexed sigil
#

The SOs are used as blueprints. They construct Spell<T> when it awakes and that data is inserted.

atomic sapphire
#

i see

hexed sigil
#

Spell<T> basically just has the behaviors and the control logic

#

SO -> Damage, Speed, ect

atomic sapphire
#

so u have a base spellSO and other types of spells and their SO's that inherit from base and then have one generic class that handles the logic of ANY spell regardless of what exactly it is

#

right?

#

or did i get it terribly wrong or smth

#

but surely the logic of spell projectile is different than the logic of spell area

#

u cant really generalize them

hexed sigil
#

Right, the base Spell<T> provides a lot of logic that the other spell classes may need like target and direction, but it makes no sense to say that Spell<T> has any logic involving speed, as only the Projectile/ProjectileSO cares about that

hexed sigil
#

Meanwhile SpellArea/AreaSO has maybe radius

atomic sapphire
#

yeah what happens here then?

#

do we have to include another class then inside the generic class?

#

no right that sounds bad

#

can we make functions inside the generic class that have constraints as well? like CastAreaDamage() can only be called if T is areaspell

hexed sigil
#

Kinda, but that defeats some purpose. You want the base the share between all extended classes

atomic sapphire
#

then we're back to where we started

#

we'd now need to make a new class for each spells own unique logic

hexed sigil
#

Like the base can have a bunch of abstract methods too yeah. ApplyDamage() may be used different between each of them

fresh grail
#

here's maybe another way to look at it:
generics are another way to reduce repetition, like inheritance or functions
functions reduce repetition where the logic is the same, but the parameters or calling context change
inhertiance reduces repetition where the core/base behavior is the same, but some details change, or behavior is added
generics reduce repetition where the structure and behavior are the same - the functions and variables and such - but the types change

atomic sapphire
#

ah i see

#

that makes sense

#

id obv need to use them more to actually grasp them but i get the core idea of them now

hexed sigil
#

Like you can be fine by just casting everything, but you need to make sure that the data being implemented in these classes are correct, while the constraints that I'm doing here do prevent that.

atomic sapphire
#

yeah i get u

hexed sigil
#

Because without the constraint here you could have a downcasted rather upcasted SO and you will error if you don't check the typing.

atomic sapphire
#

i heard abt the implemented type safety generics use which is another reason i was thinking abt them

#

anyways thanks for the help

fresh grail
#

you wouldn't want to write this once for each thing you want to randomize, but you also wouldn't want an object return that you have to cast

mild laurel
placid girder
#

generics are useful because they allow the consumer of your code to be more specific than your code is (in a type-safe way)

elfin orchid
placid girder
#

an interesting observation is that you don't need generics for most things, strictly speaking

#

you could just have a List<object> and make sure you always put the right kind of thing in it

#

(and, indeed, that's what you had to do in Java in the olden days..)

verbal bobcat
#

One usecase for generics might for exmaple be a Singleton class you can inherit from that safely checks for instances and what not and let the user just use any class with type Singleton<MyclassName> to create a static instance at runtime out of it. So you have stuff like Onenable and awake inside that singleton class which will not be touched by the inheritance but rather use wrappers to be sure to always call the Awake() and after that everything your inheritance wnats to do at awake.