I realize it is not possible to derive from a generic type parameter, and I understand all the complications that arise if it is allowed.
So my question is, how do I work around this? I am trying to eliminate some duplicate code and the best solution (which is not a solution because it cannot be done) I have come up with would be to do something like this:
public class Proxy<T> : T where T : CommonBaseClass
The reason I would want to do this is to override some methods in the CommonBaseClass.
Here is some actual code examples from my project:
public class ReportingServiceProxy : ReportingService2010
{
protected override WebResponse GetWebResponse (WebRequest request)
{
WebResponse response = base.GetWebResponse(request);
// Do override stuff here
return response;
}
}
public class ReportingExecutionProxy : ReportExecution2005
{
protected override WebResponse GetWebResponse (WebRequest request)
{
WebResponse response = base.GetWebResponse(request);
// Do override stuff here
return response;
}
}
In the example above the ReportingService2010 & ReportExecution2005 classes both derive from SoapHttpClientProtocol which derives from HttpWebClientProtocol. The override methods GetWebResponse and GetWebRequest both override methods in HttpWebClientProtocol and are identical. These methods are where the code duplication exists which I am trying to refactor out.
For completeness, here is some additional code where I implement the code above:
public abstract class SSRSReportBase<T> where T : new()
{
protected T ssrs;
protected abstract void ServiceLogon();
public SSRSReportBase()
{
ServiceLogon();
// Do other common constructor work here.
}
}
// Implementation #1
public class SSRSReportExecution : SSRSReportBase<ReportExecutionProxy>
{
protected override void ServiceLogon()
{
ssrs.LogonUser("LoginName", null, null);
}
// Create additional wrapper methods for ReportExecution2005
}
// Implementation #2
public class SSRSReportingService : SSRSReportBase<ReportingServiceProxy>
{
protected override void ServiceLogon()
{
ssrs.LogonUser("LoginName", null, null);
}
// Create additional wrapper methods for ReportingService2010
}
The only solution I have come up with is not a possible solution, so obviously it’s NOT a solution. Here is the bad code:
public class ReportProxy<T> : T where T : HttpWebClientProtocol, new()
{
protected override WebResponse GetWebResponse (WebRequest request)
{
WebResponse response = base.GetWebResponse(request);
return response;
}
}
// Implementation #1
public class SSRSReportExecution : SSRSReportBase<ReportProxy<ReportExecution2005>>
{
}
// Implementation #2
public class SSRSReportingService : SSRSReportBase<ReportProxy<ReportingService2010>>
{
}
Question: So my question is, how can this code be refactored in such a way as to remove the duplicate code (the GetWebRequest and GetWebResponse overrides)?
A solution would be to not use generics at all and to use a factory pattern. Instead of having a generic parameter with the
BaseClassand thenew()constraint. Type everythingBaseClassand provide a factory fornew(). This can be either a full-fleged factory class or a lightweight factory delegate.You might even add additional initialization code in the factory.
Using a delegate