开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜