protected override string PropToString()
 {
     return(this switch {
         ArrEntProp <int> aip => aip.Values.Select(i => CreateIntPropStr(i, FProp.DisplayType, FProp.DemoInfo)).SequenceToString(),
         ArrEntProp <float> afp => afp.Values.Select(f => CreateFloatPropStr(f, FProp.DisplayType)).SequenceToString(),
         ArrEntProp <Vector2> av2P => av2P.Values.Select(v => CreateVec2PropStr(v, FProp.DisplayType)).SequenceToString(),
         ArrEntProp <Vector3> av3P => av3P.Values.Select(v => CreateVec3PropStr(v, FProp.DisplayType)).SequenceToString(),
         ArrEntProp <string> asp => asp.Values.Select(s => CreateStrPropStr(s, FProp.DisplayType)).SequenceToString(),
         _ => throw new Exception($"bad property type: {GetType()}")
     });
        public override void CopyPropertyTo(EntityProperty other)
        {
            ArrEntProp <T> casted = (ArrEntProp <T>)other;

            casted.Offset    = Offset;
            casted.BitLength = BitLength;
            for (int i = 0; i < Values.Count; i++)
            {
                if (i >= casted.Values.Count)
                {
                    casted.Values.Add(Values[i]);
                }
                else
                {
                    casted.Values[i] = Values[i];
                }
            }
        }