Your code is strange and you should never write like that, because its absence is behind the type safety mask!
See the heading of your class:
public class Inventory<T> where T : InventoryItem
what is written here? And it says that a class can receive as a generic parameter of any successor of the InventoryItem !
Those.:
public class SuperInventoryItem : InventoryItem { }
and somewhere
var invertory = new Inventory<SuperInventoryItem>();
Guess what happens here? And better run and check!
I hope you understand that if B is A , then the opposite is not true in the general case? This is what the compiler tells you, and therefore, in general, new A() as B will return null !
So you have 2 ways:
If your program does not foresee any successors of the InventoryItem , then you generally do not need to introduce such restrictions: T : InventoryItem , just work inside exclusively with the InventoryItem , and not T I would, for loyalty, then make the InventoryItem class also sealed .
If you have InventoryItem descendants in your program and the class should be able to create them, then you should master the "Factory" pattern and transfer the Inventory factory to the InventoryItem designer. This will make your code cleaner: the Inventory class doesn’t have to know how any InventoryItem created and configured. .