Родовое свойство типа T до известного наследующего типа

Я получаю следующую ошибку компилятора

Невозможно преобразовать тип 'T' в 'ProjectReportingHandler'

для линии

var projectReport = (ProjectReportingHandler)result.Report;

при попытке скомпилировать:

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;
    }
}

Любые идеи о том, как привязать свойство связанного родового типа result.Report к ProjectReportingHandler?

Я бы подумал, что where T : ReportingHandler гарантировал бы, что это возможно: (

EDIT: Кажется, я получаю несколько ответов, которые говорят, что мой принятый ответ неверен. Он работает, и я реализовал его следующим образом:

public 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;
}

Почему пустые голоса за ответ, который сработал?: (

Ответы

Ответ 1

Вы можете "обмануть" результат первой кастинга. Вернитесь к объекту, а затем в ProjectReportingHandler.

Ответ 2

where T : ReportingHandler недостаточно.
Что произойдет, если T - это другой тип, который наследует ReportingHandler, но не ProjectReportingHandler?

Если вы уверены, что T всегда наследуется от ProjectReportingHandler, вы можете изменить ограничение на where T : ProjectReportingHandler.

Если вы действительно хотите сделать это так, как вы делаете это сейчас, сначала нужно указать ReportingHandler, например:

var projectReport = ((ReportingHandler)result.Report) as ProjectReportingHandler;

Если T не наследует ProjectReportingHandler, projectReport будет null.

Ответ 3

T: ReporingHandler не гарантирует, что преобразование возможно. Просто потому, что ProjectReportingHandler является ReportingHandler, не означает, что обратное верно.

Ответ 4

Как насчет использования as:

        ReportInstance<T> result = new ReportInstance<T>();
        var projectReport = result.Report as ProjectReportingHandler;
        if (projectReport != null)
        {
            //do stuff
        }