我正在尝试结束对抽象方法和返回类型协方差的两天抨击,我已经发布了两个类似的问题,我永远感谢社区提供的信息,我只需要最后一次推动即可终点线。这是我想要做的:2 个抽象类,RecruiterBase 和 CandidateBase,它们都有 RecruiterA 和 CandidateA 的 concreate 实现。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 中遇到了以下问题
这最终让我意识到我一直在寻找的是一种为我的返回类型实现协方差的方法。我使用了 Marc Gravell 的片段......
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 包你最喜欢的啤酒!