An alternative to the C# generic new() constraint
November 12, 2007 – 3:33 pmHere’s something I came up with other the weekend while playing with some code…
I wanted to write a method that ensured that some object of type T was always available.
ModelElement element = EnsureElementExists<ModelElement>(_store);
Unfortunately in this case the ModelElement class does not have a parameterless constructor. This means I can’t use the where T:New() constraint and then just create a new instance in my generic method. What I can do is use a delegate to provide a new instance of the object if I need it:
public delegate T ConstructorDelegate<T>() where T : class; public static T EnsureElementExists<T>(Store store, ConstructorDelegate<T> ctor) where T : ModelElement { T element = store.GetElement<T>(); if (element == null) element = ctor(); return element; }
This means I can now write code like this where DiagramElement (a class derived from ModelElement) is created by the delegate:
DiagramElement diagramElement = EnsureElementExists<DiagramElement>(_store, delegate() { return new DiagramElement(_store); });
Calls to EnsureElementExists can use the anonymous delegate to create a new DiagramElement with a parameterized constructor.






3 Responses to “An alternative to the C# generic new() constraint”
Nifty idea…the only thing I’m wondering about is why you have a where constraint on ConstructorDelegate. It seems like that would overtly constraint your open-ended solution.
And just to be nitpicky…wouldn’t you add the object you just created in your if block so you wouldn’t keep creating it?
Again, good idea - I like this :)
By Jason Bock on Nov 13, 2007
Nice catch Jason,
I’ve updated the code to reduce the constraint on ConstructorDelegate and fixed the if statement.
Ade
By Ade on Nov 13, 2007