Create instance of generic type?


Question

If BaseFruit has a constructor that accepts an int weight, can I instantiate a piece of fruit in a generic method like this?

public void AddFruit<T>()where T: BaseFruit{
    BaseFruit fruit = new T(weight); /*new Apple(150);*/
    fruit.Enlist(fruitManager);
}

An example is added behind comments. It seems I can only do this if I give BaseFruit a parameterless constructor and then fill in everything through member variables. In my real code (not about fruit) this is rather impractical.

-Update-
So it seems it can't be solved by constraints in any way then. From the answers there are three candidate solutions:

  • Factory Pattern
  • Reflection
  • Activator

I tend to think reflection is the least clean one, but I can't decide between the other two.

1
205
5/26/2015 12:42:13 PM

Accepted Answer

Additionally a simpler example:

return (T)Activator.CreateInstance(typeof(T), new object[] { weight });

Note that using the new() constraint on T is only to make the compiler check for a public parameterless constructor at compile time, the actual code used to create the type is the Activator class.

You will need to ensure yourself regarding the specific constructor existing, and this kind of requirement may be a code smell (or rather something you should just try to avoid in the current version on c#).

300
12/16/2014 11:21:09 AM

You can't use any parameterised constructor. You can use a parameterless constructor if you have a "where T : new()" constraint.

It's a pain, but such is life :(

This is one of the things I'd like to address with "static interfaces". You'd then be able to constrain T to include static methods, operators and constructors, and then call them.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon