1

Can anyone tell me why I can't add to a list a wrapper containing generic class that have inheritance ?

public abstract class SectorObject{} 
public class SpawnPoint : SectorObject
public class Trigger : SectorObject
public class SectorObjectList<T>  where T : SectorObject { public List<T> items ; };


public List<SectorObjectList<SectorObject>> objectLists = new List<SectorObject< SectorObject>>();

SectorObjectList <SpawnPoint> spawnPoints = new SectorObjectList<SpawnPoint>();

objectLists.Add(spawnPoints);  // This line doesn't work.

It works only as this :

public List<SectorObjectList<SpawnPoint>> objectLists = new List<SectorObject< SpawnPoint>>();
SectorObjectList <SpawnPoint>spawnPoints = new SectorObjectList<SpawnPoint>();
objectLists.Add(spawnPoints);  

Cheers.

CodeSmile
  • 64,284
  • 20
  • 132
  • 217
user2550696
  • 111
  • 2
  • 11
  • What (probably useful) information is the compiler telling you? – James Thorpe Nov 07 '14 at 13:56
  • The best overloaded method match for `System.Collections.Generic.List>.Add(SectorObjectList)' has some invalid arguments – user2550696 Nov 07 '14 at 14:07
  • It seems weird. I don't get it why there is no such overloaded method, when i use inheritance. – user2550696 Nov 07 '14 at 14:10
  • I guess the compiler doesn't see what `SectorObjectList` doesn't derive from `SectorObjectList` - at the end of the day, generics are really just syntactic sugar that prevent you having to write almost identical classes etc. The two types here aren't really related in the same way that just `SectorObject` and `SpawnPoint` are. You can always just use a list of the base class, there's nothing stopping you adding `SpawnPoint`s to such a collection – James Thorpe Nov 07 '14 at 14:14

1 Answers1

1

Classic covariance / contravariance problem. You can find lots of related posts on Stack Overflow, like this one. Without casting and conversions you should use your abstract class for declarations and the concrete classes for initialization:

List<SectorObjectList<SectorObject>> objectLists = 
    new List<SectorObjectList<SectorObject>>();
SectorObjectList<SectorObject> spawnPoints = new SectorObjectList<SectorObject>();
spawnPoints.items = new List<SectorObject>();
spawnPoints.items.Add(new SpawnPoint());
objectLists.Add(spawnPoints);

If your SectorObjectList was bound to SpawnPoint explicitly, then you could get away with casting your adaptee:

var spawnPoints2 = new SectorObjectList<SpawnPoint>() { 
    items= new List<SpawnPoint>()};
var spawnPointsCopy = new SectorObjectList<SectorObject>() { items= spawnPoints2.items.Cast<SectorObject>().ToList() };
objectLists.Add(spawnPointsCopy);  
Community
  • 1
  • 1
andrei.ciprian
  • 2,895
  • 1
  • 19
  • 29