I have an interface ISnack which when implemented by a class, it should have a default parameterless constructor. Basically this:
public interface ISnack<T> where T : new()
{
}
I use <T> where T : new() just to enforce the parameterless constructor.
I would then implement the interface this way:
public class Cutlet : ISnack<Cutlet>
{
}
This works and it simply ensures Cutlet class has a parameterless constructor.
Now I have an abstract base class Kitchen:
public abstract class Kitchen<T> where T : ISnack
{
}
The requirement is that Kitchen should have constraint where T should be an ISnack. But this wont work because there exists no ISnack, but only ISnack<T>.
If I tried this
public abstract class Kitchen<T> where T : ISnack<T>
{
}
it wouldn’t compile ('T' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ISnack<T>') and also wouldn’t make sense in my context.
If I could force ISnacks to have a parameterless constructor without constraining by a T type parameter, then T in Kitchen<T> could easily be an ISnack. How to go about it?
You can’t unless you add the constraint; generic constraints are cumulative, so to make the compiler happy you would have to have:
If that is fine, then do that. If it isn’t fine, then you’ll have to remove the
: newfrom the original, and make do without it. This isn’t as bad as it sounds, but it means you push validation down to execution rather than compilation. But:Activator.CreateInstance<T>()still does what you would need, anyway – even without thenew()constraint. So you can replace:with:
A handy trick when removing constraints can be: add a unit/integration test that finds the candidate types via reflection, and validate the missing constraint as part of your test suite.