'C# How to access a class reference using a string
So, I have spent about 3 hours so far trying to find a solution
But, it is hard to understand the topics so high above my current knowledge.
QUESTION
If I have a base-class called Spell , and Sub-Classes such as HolySmite or DivineBuff , is there any possible way to access those classes by using a string?
MORE INFORMATION
I have a bunch of spells, ALL of them have simple variables such as refreshTimer or manaCost
I am trying to use one simple method called CastSpell()
This Method has about 30 lines of code such as:
- is it time yet to cast spell?
- do we have enugh mana to cast the spell?
- did we complete casting the spell (because it took 10 seconds to cast it)?
*
Currently, I am having to manually do all 30 lines of code multiplied by all the spells that I have, so far 30. It is very repetitive and makes it difficult read.
EXAMPLE Right now VERSUS what I want to do:
// this string can be any spell, I have 30 spells so far but will be adding more
string spellName = "HolySmite";
// Currently, I am having to write 30 lines of code attached below, and then I have to repeat the same damn thing for 30 spells
// Lets just use only 1 line of code as an example...
if (spellName == "HolySmite")
{
Spell.holySmite.castingNow = true;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< INSTEAD HOW CAN I GENERICALLY ACCESS THE CLASS FROM A STRING >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Spell.spellName.castingNow = true;
// Obviously, spellName does not exist inside the class. I just want to access the class called "HolySmite"
// -- which is the variable stored in string spellName;
//
// Someone suggested using a Dictionary GET/SET inside the class:
//
//public class Spell
// {
// public Dictionary<string, SpellInfo> Spells = new Dictionary<string, SpellInfo>()
// {
// { nameof(HolySmite), new HolySmite() },
// { nameof(DivineBuff), new DivineBuff() }
// }
// }
//
// However, using Dictionary prevents me access the subClass properties such as: refreshTimer, radius, damage, etc, etc, etc, etc
//
// THERE MUST BE SOME OTHER WAY!
HERE IS THE CLASS DEFINITIONS
public string spellName;
// My nested/inherted class
public abstract class SpellInfo
{
public float timeToCastSpell;
public float refreshTimer;
public int manaCost;
public float lastTimeCompleted;
public float lastTimeAttempted;
public bool castingNow;
public abstract void Action();
}
// DERIVES from SpellInfo
public class HolySmite : SpellInfo
{
public float radius;
public int damage;
public override void Action()
{
Debug.Log("Casting HolySmite");
}
}
public class DivineBuff : SpellInfo
{
public override void Action()
{
Debug.Log("Casting DivineBuff");
}
}
public class Spell
{
public static HolySmite holySmite = new HolySmite();
public static DivineBuff divineBuff = new DivineBuff();
}
Solution 1:[1]
Consider re-writing your spell class so that instead of having everything in a big long list of if statements, you use an interface to say a spell can act upon a target:
interface ISpell
{
void CastOn(Player target);
}
Then your actual concrete spell class would look like:
class HolySmite : ISpell
{
//other properties
private int Damage = 15;
public CastOn(Player target)
{
target.Health -= Damage;
}
}
class DivineBuff : ISpell
{
//other properties
private int Resistance = 0.1;
public CastOn(Player target)
{
target.Resistance += Resistance;
}
}
Then, only the CastOn method needs to know about all the properties of the spell, and you can use a dictionary like you were recommended:
Dictionary<string, ISpell> Spells = new Dictionary<string, ISpell>
{
{nameof(HolySmite), new HolySmite()},
{nameof(DivineBuff), new DivineBuff()}
};
Then, when you cast a spell, you simply say
var spellName = "HolySmite";
Spells[spellName].CastOn(myTarget);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | RoadieRich |
