Я пытаюсь завершить двухдневный анализ методов Abstract и типа возврата Covariance, я уже опубликовал два похожих вопроса и я бесконечно благодарен сообществу за предоставленную информацию, мне просто нужен последний толчок добраться до финиша. Вот что я пытаюсь сделать: два абстрактных класса, RecruiterBase и CandidateBase, оба имеют конкретные реализации RecruiterA и CandidateA. RecruiterBase имеет абстрактный метод для получения всех завербованных кандидатов, возвращающих IQueryable. Моя реализация RecruiterA переопределяет метод GetCandidates () для возврата IQueryable.
public abstract class RecruiterBase
{
// Constructors declared here
public abstract IQueryable<CandidateBase> GetCandidates();
}
public abstract class CandidateBase
{
// Constructors declared here
}
и реализации:
public class CandidateA : CandidateBase
{
// Constructors declared here
}
public class RecruiterA : RecruiterBase
{
// Constructors declared here
// ----HERE IS WHERE I AM BREAKING DOWN----
public override IQueryable<CandidateA> GetCandidates()
{
return from c in db.Candidates
where c.RecruiterId == this.RecruiterId
select new CandidateA
{
CandidateId = c.CandidateId,
CandidateName = c.CandidateName,
RecruiterId = c.RecruiterId
};
}
}
Попытка компилировать, которая выдает ошибку времени компиляции, потому что в моей реализации RecruitreBase метод GetCandidates () возвращает IQueryable<CandidateA>
вместо IQueryable<CandidateBase
>.
После того, как я не смог получить предложения из предыдущего вопроса ( Универсальные типы возвращаемых данных из абстрактных / виртуальных методов ), я прочитал ОЧЕНЬ МНОГО ЧИТАТЬ и натолкнулся на следующий вопрос в SO
Как вернуть подтип в переопределенном методе подкласса в C #?
Что, наконец, заставило меня понять, что я искал способ реализации Covariance для моего возвращаемого типа. Я использовал фрагмент Марка Гравелла ...
abstract class BaseClass
{
public BaseReturnType PolymorphicMethod()
{ return PolymorphicMethodCore();}
protected abstract BaseReturnType PolymorphicMethodCore();
}
class DerivedClass : BaseClass
{
protected override BaseReturnType PolymorphicMethodCore()
{ return PolymorphicMethod(); }
public new DerivedReturnType PolymorphicMethod()
{ return new DerivedReturnType(); }
}
... как основа для моего решения. Так что теперь мои классы RecruiterBase и RecruiterA выглядят так:
public abstract class RecruiterBase
{
// Constructors declared here
public IQueryable<CandidateBase> GetCandidates()
{
return GetCandidatesCore();
}
public abstract IQueryable<CandidateBase> GetCandidatesCore();
}
и моя реализация ...
public class RecruiterA : RecruiterBase
{
// Constructors
protected override IQueryable<CandidateBase> GetCandidatesCore()
{
return GetCandidates();
}
public new IQueryable<CandidateA> GetCandidates()
{
return from candidates in db.Candidates
select new CandidateA
{
CandidateId = candidates.CandidateId,
RecruiterId = candidates.RecruiterId
};
}
}
Я надеялся, что это наконец-то даст мне то, что я искал, но я получил ошибку времени компиляции в следующем коде, потому что GetCandidates () не может неявно преобразовать CandidateA в CandidateBase:
protected override IQueryable<CandidateBase> GetCandidatesCore()
{
return GetCandidates();
}
поэтому я добавил приведение:
protected override IQueryable<CandidateBase> GetCandidatesCore()
{
return ((IQueryable<CandidateBase>)GetCandidates());
}
Затем все компилируется, но когда я на самом деле вызываю GetCandidates () в моем контроллере, он возвращает IQueryable<CandidateBase>
вместо IQueryable<CandidateA>
. Так что я вернулся к тому, с чего начал.
Если вы прошли через все это и можете мне помочь, я отправлю вам 12 пачек вашего любимого пива!