Cast generic property of type T up to a known inheriting type
I'm getting the following compiler error
Cannot convert type 'T' to 'ProjectReportingHandler'
for the line
var projectReport = (ProjectReportingHandler)result.Report;
when trying to compile:
public abstract class ReportingHandler
{
// Report stuff
}
public abstract class ProjectReportingHandler: ReportingHandler
{
// Report stuff
// Project specific report stuff
}
public class ReportInstance<T>
where T : ReportingHandler
{
public T Report { get; private set; }
}
public class ReportLibraryEntry<T>
where T : ReportingHandler
{
public ReportInstance<T> Create()
{
ReportInstance<T> result = new ReportInstance<T>();
if (result.Report is ProjectReportingHandler)
{
var projectReport = (ProjectReportingHandler)result.Report;
// do stuff with project reports
}
return result;
}
}
Any ideas how to cast the linked generic type property result.Report
to a ProjectReportingHandler
?
I would have thought the where T : ReportingHandler
would have ensured this was possible :(
EDIT: I seem to be getting a few responses that say my accepted answer is incorrect. It works, and I implemented it as follows:
pu开发者_开发百科blic ReportInstance<T> Create()
{
ReportInstance<T> result = new ReportInstance<T>();
ReportingHandler report = result.Report;
if (report is ProjectReportingHandler)
{
var projectReport = (ProjectReportingHandler)report;
// do stuff with project reports
}
return result;
}
Why the down votes for an answer that worked? :(
where T : ReportingHandler
is not enough.
What should happen if T
is some other type that inherits ReportingHandler
but not ProjectReportingHandler
?
If you're sure that T
will always inherit from ProjectReportingHandler
, you can change the constraint to where T : ProjectReportingHandler
.
If you really want to do it the way you're doing it now, you should first cast to ReportingHandler
, like this:
var projectReport = ((ReportingHandler)result.Report) as ProjectReportingHandler;
If T
does not inherit ProjectReportingHandler
, projectReport
will be null
.
T : ReporingHandler does not guarantee that that the conversion is possible. Just because a ProjectReportingHandler is a ReportingHandler doesn't mean the opposite is true.
How about using as
:
ReportInstance<T> result = new ReportInstance<T>();
var projectReport = result.Report as ProjectReportingHandler;
if (projectReport != null)
{
//do stuff
}
You can "cheat" by first casting result.Report to an object, and then to a ProjectReportingHandler.
精彩评论