Reputation: 334
NOTE: In order to write a reasonably short question, I create an example similar to the troubled area of my application. The actual example is more complex but the problem statement is accurate.
Say I have an abstract base class:
public abstract class AnalysisObject
{
public virtual AnalysisObject CreateObject(int id, string description)
{ return null; }
//Some other virtual methods in here
}
I derive some classes from it that contain behavior specific to some AnalysisObject types. For example:
public class HWAnalysisObject : AnalysisObject {
public override AnalysisObject CreateObject(int id, string description)
{
return new HWAnalysisObject();
}
//override more virtual methods to provide specific behavior
}
Now, I want to write a generic service that can operate on AnalysisObjects. In this service I at some point need to create and return new subtypes of AnalysisObject. And I can't figure out how to do that.
public class AOService<TAnalysisObject> where TAnalysisObject : AnalysisObject
{
public AnalysisObject FetchObject(int id)
{
return TAnalysisObject.CreateObject(id, "new object");
}
That does not compile, obviously: "TAnalysisObject is a type parameter, which is not valid in this context."
Fair enough. But how can I use the properties, etc of the type that I pass in to my service so I know what kind of subclass to return? I feel like I'm missing Generics 101 here, which is fair enough because I usually use generic classes and services, I do not write them.
I could stick a method in the service that looks like this:
private AnalysisObject MakeAnalysisObject(int id, string description)
{
if ( (typeof(TAnalysisObject) == typeof(HWAnalysisObject) )
{
return new HWAnalysisObject(id, description);
}
if ( (typeof(TAnalysisObject) == typeof(MMAnalysisObject) )
{
return new MMAnalysisObject(id, description);
}
//etc
}
But I feel that defeats the purpose of why I tried generics: now I can't just derive more AnalysisObject and have the service just able to take care of them: I have to maintain this method in the service every time I add a new type.
Upvotes: 1
Views: 166
Reputation: 77304
The new()
constraint means your class needs to have a parameterless constructor. Then you can create a new one with new T();
. There is no way to enforce another than the parameterless constructor though.
public class AOService<TAnalysisObject> where TAnalysisObject : AnalysisObject, new()
{
public AnalysisObject FetchObject(int id)
{
return new TAnalysisObject();
}
}
Upvotes: 2