I am trying to make a c# mod for a game. In order to do so, first I wanted to recreate some classes, methods, etc. in a simpler way. So far I have this code (everything is in the same namespace):
class MyWeapons
{
public class SL_Item
{
public SL_ItemStats StatsHolder;
public int New_ItemID;
public int Target_ItemID;
}
public class SL_Weapon : SL_Item
{
public bool? Unblockable;
public float? HealthLeechRatio;
}
public class SL_Damage
{
public float Damage;
public string Type;
}
public class SL_ItemStats
{
public int BaseValue;
}
public class SL_WeaponStats : SL_ItemStats
{
public List<SL_Damage> BaseDamage;
public float AttackSpeed;
}
}
public static void Init()
{
var myItem = new SL_Weapon()
{
StatsHolder = new SL_WeaponStats()
{
//adding new SL_Damage to the BaseDamage list when initializing it
BaseDamage = new List<SL_Damage>() { new SL_Damage { Damage = 25f, Type = "Something" } },
}
};
myItem.StatsHolder.AttackSpeed = 5f;
}
Now, the problem is, that in the last line the program 'thinks' that AttackSpeed is a property of SL_ItemStats (because StatsHolder is of that type; the error says: SL_ItemStats does not contain a definition for AttackSpeed...). But the class SL_WeaponStats inherits from SL_ItemStats and I made StatsHolder a new object of the type SL_WeaponStats. Now, the thing I absolutely don't understand is that I can access StatsHolder properties of the SL_WeaponStats class in the object initializer (BaseDamage in my code; but I also tried with AttackSpeed and it works fine). However I cannot access the same properties after the object (myItem) already exists (the last line).
CodePudding user response:
Works by design.
public class SL_Item
{
// you declared StatsHolder as SL_ItemStats
public SL_ItemStats StatsHolder;
.....
// you derived to its superclass
StatsHolder = new SL_WeaponStats()
your expectations are false because StatsHolder does not have AttackSpeed. The base SL_WeaponStats has it.
This works
((SL_WeaponStats)myItem.StatsHolder).AttackSpeed = 5f;
CodePudding user response:
You are hitting upon the distinction between an object's static type and its dynamic type.
The dynamic type of a variable is the type of the object it holds while running.
The static type of a variable is the type it's defined as in the code.
The compiler can only know a variable's static type. StatsHolder is defined as a SL_ItemStats, so as far as the compiler is concerned, that's all it can be. T.S.'s answer shows how to enlighten the compiler as to the wider uses of StatsHolder.
