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 (eg: 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, eg:
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 in to 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 in to it as the constructor specifies.
Pretty ingenious!