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
.