C# Generic Type Inheritance

Hey everyone.
I have some problems with the inheritance of Generic classes.
In the example below there is a exception thrown when I try to initialize the List…
It seems like it can’t cast from MiningBuilding (Building) to Building.
I’ve heard that this should be possible in Java.
Does anyone see a solution for this?

Not tested Code:

abstract class BuildingType : ScriptableObject{ }
class MiningBuildingType : BuildingType { }
abstract class Building<T> where T : BuildingType 
{
  public T Type;
}
class MiningBuilding : Building<MiningBuildingType> 
{ 
  public MiningBuilding(T type)
  {
    Type = type;
  }
}

..
public MiningBuildingType type;
List<Building<BuildingType>> buildings = new List<Building<BuildingType>>(){ new MiningBuilding(type) };

Hi, To simplify your example allow me to take the list and the generic definition out of the equation. What you are trying to do is casting a class to another incompatible class implicitly without providing a mechanism telling the compiler how to do the casting.

Class A {}
Class B {}
...
A obj = new B();

The code above will generate the same error you got because A and B are 2 separate types.

To solve this error you have 2 options, either you implement a user defined type conversion like this

public class B 
{
    public static implicit operator A(B obj)
    {
	    return new A();
    }
}

or you just simply make B inherits from A.

Now lets get back to the generic class definition, take a look at the following example

//Behaviour is a Unity class where MonoBehaviour inherits from
Class A<T> where T : Behaviour {}
A<Behaviour> aBehaviour = new A<MonoBehaviour>();

this will not compile successfully because the generic class A(Behaviour) is completely different than A(MonoBehaviour) even though MonoBehaviour is related to Behaviour and both types are supported by class A.

Put all that aside, IMO I see no need to have a generic class in your case, it just makes your code unnecessarily complicated. If you just do the following all will be fine.

Class Building {}
Class MiningBuilding : Building {}

You can’t have a constructor like this:

class MiningBuilding : Building<MiningBuildingType>
{
    public MiningBuilding(T type)
    {
        Type = type;
    }
}

MiningBuilding could only have field “Type” of type MiningBuildingType (type of type lol)

class MiningBuilding : Building<MiningBuildingType>
{
    public MiningBuilding()
    {
        Type = new MiningBuildingType();
    }
} 

Now declaring a List like this:

List<Building<BuildingType>>

won’t let you to create it, because you can’t create any instance of abstract class (building)

Adding intermediate building class can enable you to create generic list of buildings:

abstract class BuildingBase<T> where T : BuildingTypeBase
{
    public T Type;
}

abstract class BuildingTypeBase
{

}
class MiningBuildingType : BuildingTypeBase { }

class Building : BuildingBase<BuildingTypeBase>
{

}

class MiningBuilding : Building
{
    public MiningBuilding()
    {
        Type = new MiningBuildingType();
    }
}

public class Test
{
    List<Building> buildings = new List<Building>();
    void myCode()
    {
        var b = new MiningBuilding();
        buildings.Add(b);
    }

}