Pretty cool trick I found today on StackOverflow.
I’ve often struggled with the fact that when you’re writing a generic method, while you can constrain the type of the method, you can only specify the constraint of having a constructor, and even then, only a default constructor (e.g.: new()
); not one with parameters. Since I can constrain the type, which can in-turn constrain the constructor, it seems that I should be able to do:
public T CreateMe<T>(int param) where T : MyClass
{
return new T(param);
}
but alas, we can’t. At best, we could new up the type-constrained object, but only if you’re constraining to a non-abstract class and not an Interface or abstract class, e.g.:
public T CreateMe<T>(int param) where T : MyClass
{
return new MyClass(param);
}
but that won’t give us the type that we passed in as our generic.
So to re-iterate what’s posted in the StackOverflow link, the solution is to pass a Func<[param type(s)], T>
creator into the method like so:
public T CreateMe<T>(int param, Func<int, T> creator) where T : MyClass
{
return creator(param);
}
Then, you just use it like this:
public class MyDerivedClass : MyClass
{
public MyDerivedClass(int param) : base(param) { }
}
var myInstance = CreateMe(1, (p) => new MyDerivedClass(p));
Which will spin up an instance of MyDerivedClass
but pass the ‘1
’ parameter into it as the constructor specifies.
Pretty ingenious!