C # Соответствие подписи шаблонного метода для переопределения в производном классе - PullRequest
0 голосов
/ 24 октября 2018

Редактировать: я получил несколько комментариев, идентифицирующих это как дубликат и связывающих с определениями виртуальных, переопределенных и других подобных ключевых слов, однако это не полный ответ, который я ищу.Ниже в оригинальном сообщении я заявляю, что пытался использовать виртуальные и переопределить ключевые слова, но получил ошибку компилятора.Первоначально я пропустил эти ключевые слова в коде, потому что он не компилировался, но я поместил их сейчас, чтобы сфокусировать проблему на том факте, что сигнатура метода производного класса недостаточно совпадает, чтобы иметь возможность переопределить метод базового класса,Простое добавление этих ключевых слов не решает мою проблему.Прочитав ответы, которые я получил, я понял, что мне нужна помощь для компиляции кода и достижения результатов, которые я ищу.


Привет, у меня есть код, который выглядит примерно так:

// WeeklyReport.cs
public class WeeklyReport: Report {
    // class definitions
}

// ReportService.cs
public class ReportService
{
    public async Task<ResponseMessage> ChangeStatus<T>(string reportId, string status) where T:Report, new()
    {
         var report = await SelectReportById<T>(reportId);
         // do stuff
         return await SetStatus(change, report);
    }

    public virtual async Task<ResponseMessage> SetStatus<T>(StatusChange change, T report) where T : Report, new()
    {
        // do stuff
    }
}

// WeeklyReportService.cs
public class WeeklyReportService : ReportService
{
    // This method does not compile!!!
    public override async Task<ResponseMessage> SetStatus(StatusChange change, WeeklyReport report)
    {
        // do stuff
    }
}

Краткое описание кода выше:

У меня есть два класса моделей, Report & WeeklyReport.WeeklyReport является подклассом Report

У меня есть два класса обслуживания, ReportService и WeeklyReportService.WeeklyReportService является подклассом ReportService и пытается переопределить его метод SetStatus ()

Проблема:

Когда я вызываю ChangeStatus () для экземпляра WeeklyReportService.Я хочу, чтобы SetStatus (), как определено в WeeklyReportService, вызывалось вместо SetStatus (), как определено в ReportService.

Я уже пытался добавить виртуальные и переопределить ключевые слова в сигнатуры метода, но я получаю 'WeeklyReportService.SetStatus (Изменение StatusChange, отчет WeeklyReport) ': не найден подходящий метод для переопределения.

Кто-нибудь знает, как мне этого добиться?

Спасибо, Итан

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Невозможно (AFAIK) сделать именно то, что вы хотите, но вы должны быть в состоянии сделать:

public class WeeklyReportService : ReportService
{
    public override Task<ResponseMessage> SetStatus<T>(StatusChange change, T report) where T : Report, new()
    {
        if (report is WeeklyReport weeklyReport)
            return SetWeeklyReportStatus(change, weeklyReport);
        return super.SetStatus(change, report);
    }
    async Task<ResponseMessage> SetWeeklyReportStatus(StatusChange change, WeeklyReport report)
    {
        report.Status = change;
        await report.SaveChanges(); // or whatever
        return MakeResponseMessage();
    }
}

(вы можете добавить «async» и «await» к ReportService.SetStatus, но беззная больше о том, как ваш код может быть реализован, я не могу сказать, будет ли он полезен)

0 голосов
/ 24 октября 2018

Здесь происходит небольшое смешение понятий.В C # нет шаблонов (специализаций) обобщений.Вы можете переопределить с помощью точно такой же сигнатуры виртуальный метод, но вы не можете предоставить реализацию для конкретного типа, которая будет автоматически выбираться и запускаться в зависимости от типа.

Здесь вы должны переопределить тип параметра T, но ваша производная реализация (которая, в отличие от базового класса, знает, что WeeklyReport существует) будет проверять тип, приводить к WeeklyReport и вызывать перегрузку, зависящую от типа (не переопределять).

То, на что это похоже, является желательным, это абстрактный ReportService, где T - это Report, а также производный WeeklyReportService: ReportService.

...