Я пытаюсь завершить двухдневную работу по абстрактным методам и возвращаемому типу ковариации, я уже опубликовал два похожих вопроса, и я бесконечно благодарен сообществу за предоставленную информацию, мне просто нужен последний толчок, чтобы добраться до финишная черта. Вот что я пытаюсь сделать: 2 абстрактных класса, 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
Как вернуть подтип в переопределенном методе подкласса в С#?
Что, наконец, заставило меня понять, что я искал способ реализовать ковариацию для моего возвращаемого типа. Я использовал фрагмент Марка Гравелла...
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 упаковок вашего любимого пива!