Accessing a Class using only a string

Lets say I have a base-class called Spells, inside of it are many sub-classes called HolySmite and DivineBuff

For Example:

Spells.HolySmite.manaCost = 3;
Spells.DivineBuff.manaCost = 5;

To cast these spells, I have to run like 30 lines of code checking various things. But right now, I am having to manually type out those 30 lines of code multiplied by 30 spells is over 300 lines of code! And expanding!!!

Is there any way to reference to a sub-class using only a string which shares the same name?

Here is what I would like to do:

string spellName = "HolySmite";

Spells.[spellName].manaCost = 0;
//At runtime it would access the sub-class "HolySmite"
//Spells.HolySmite.manaCost = 0

Caveat, A kind fellow programmer named Hellium gave the wonderful suggestion to use a Dictionary inside of the Spell base class, but it negates the benefits of using inheritance because it prevents me accessing the sub-class properties.

i don’t really see a good way to do what you want to do here. Especially since it does not really solve the issue right?

If i correctly understand your question then (assuming your SpellBase class has 10 parameters) you do not want to write those 10 lines of value assignements per spell that is derived from your base right?

have you considered to make your base spellclass a scriptable object? This way you can create instances of derived classes as assets and fill in the values in the inspector. This should get rid of the need to write the definitions out again.

Other then that you could tag your spell classes as [Serializable] and save them to a json. Then you can modify that json and load all values from there on startup.

In general there is no real good solution to this. If you want to have a spell, you need to assign all its values. If you have many values and many spells then this has to be done. For some things there are no good shortcuts.

what about using:
FindObjectsOfType();

I would use a Dictionary for this. You can still access the sub-class:

Dictionary<string, Spells> spellsDictionary;

// Initialise the dictionary and fill it with your spells, then at some point:

var foundSpell = spellsDictionary["HolySmite"];
if (foundSpell is HolySmite x)
{
    x.subclassSpecificStuffHere;
}

Personally, instead of using a string for the key, I would create a simple enum. Less worrying about typos!

public enum SpellName
{
    HolySmite,
    DivineBuff,
    SpectralSausage,
    Etc
};

// Declaring your dictionary now looks like this:
Dictionary<SpellName, Spells> spellsDictionary;
    
// And accessing it looks like this:   
    var foundSpell = spellsDictionary[SpellName.HolySmite];

Hope that helps.