0

Is there a way to implement a List<?> in a base class?

public class DyanmoObject
{
   public int PlayerId { get; set; }
   public List<T> Objects
}

public class PlayerUnitDynamo : DynamoObject { }

public class PlayerBuildingDynamo : DynamoObject { }

public class PlayerBuilding
{
   public int BuildingID{ get; set; }
}

public class PlayerUnit
{
   public int UnitID{ get; set; }
}

public void AddItems()
{
   var unitDynamo = new PlayerUnitDynamo();
   unitDynamo.Objects.Add(new PlayerUnit());

   var buildingDynamo = new PlayerBuildingDynamo();
   buildingDynamo.Objects.Add(new PlayerBuilding());
}
DidIReallyWriteThat
  • 1,033
  • 1
  • 10
  • 39
  • What do you mean by "undefined"? – Dai Mar 25 '23 at 01:12
  • Why does your `DynamoObject.Objects` property have a setter? Generally speaking, mutable collection properties (like `List<...>`) should not have `set;`). – Dai Mar 25 '23 at 01:13
  • @Dai I mean, I dont know what kind of objects will be added to the Object list until runtime. – DidIReallyWriteThat Mar 25 '23 at 01:18
  • This sounds like the [Inner-platform Effect](https://en.wikipedia.org/wiki/Inner-platform_effect); you don't know what objects will be stored so you try to make the user of your program do the design. Unfortunately this rarely works. Instead, decide on one starting data structure, get your program working with that, then extend the structure only as needed. – Dour High Arch Mar 25 '23 at 01:41
  • Does this answer your question? [A list of multiple data types?](https://stackoverflow.com/questions/4343336/a-list-of-multiple-data-types) – Heretic Monkey Mar 25 '23 at 01:44
  • @DourHighArch while I agree with you this is a massive legacy application with multiple layers of architecture and complexity. – DidIReallyWriteThat Mar 25 '23 at 02:52
  • Then maybe this is a hint to trigger a round of feature freeze and refactoring. Sales don't like that but they also don't like buggy software. They can't have both. – Fildor Mar 25 '23 at 08:56

3 Answers3

2

There is nothing in your question that suggests that you do not have the type until run-time.

This is exactly what generics are used for. By making DynamoObject a DynamoObject<T>, you can then subclass DynamoObject<T>, specifying the type at compile-time.

public class DynamoObject<T>
{
    public int PlayerId { get; set; }
    public List<T> Objects { get; set; } = new List<T>();
}

public class PlayerUnitDynamo : DynamoObject<PlayerUnit> { }

public class PlayerBuildingDynamo : DynamoObject<PlayerBuilding> { }

public class PlayerBuilding
{
    public int BuildingID { get; set; }
}

public class PlayerUnit
{
    public int UnitID { get; set; }
}

public void AddItems()
{
    var unitDynamo = new PlayerUnitDynamo();
    unitDynamo.Objects.Add(new PlayerUnit());

    var buildingDynamo = new PlayerBuildingDynamo();
    buildingDynamo.Objects.Add(new PlayerBuilding());
}
David L
  • 32,885
  • 8
  • 62
  • 93
2

If the things you will add to your list truely have no relation to each other, you can use a List<object>. Howevever, that usually points at a design issue.

Think about what they do have in common. For example, perhaps they all have a position in the game. You could define either a base class or interface describing this similarity, e.g.:

public interface IGameObject
{
    public double X { get; set; }
    public double Y { get; set; }
}

You might then have

public class Chair : IGameObject
{
    // Implement the class
}

public class Pet : IGameObject
{
    // Implement the class
}

You could then have

List<IGameObject> objects = new List<IGameObject>();

objects.Add(new Pet());
objects.Add(new Chair());
Eric J.
  • 147,927
  • 63
  • 340
  • 553
0

You can use the class object for this :

List<object> list = new List<object>();
list.Add(1);
list.Add("Hello");
foreach (var item in list)
    Console.WriteLine($"{item} - {item.GetType().Name.ToString()}");

console result

Denis
  • 1