我正在尝试结束为期两天的关于抽象方法和返回类型协方差的讨论,我已经发布了两个类似的问题,我永远感谢社区提供的信息,我只需要最后一次推动即可到达终点线。这就是我想要做的:两个抽象类,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
>.
在无法从上一个问题中获得建议之后(抽象/虚拟方法的通用返回类型 https://stackoverflow.com/questions/1330473/generic-return-types-from-abstract-virtual-methods)为了工作,我做了很多阅读,并在 SO 中遇到了以下问题
如何在C#中子类的重写方法中返回子类型? https://stackoverflow.com/questions/421851/how-to-return-subtype-in-overridden-method-of-subclass-in-c
这最终让我意识到我一直在寻找的是一种为我的返回类型实现协方差的方法。我用了马克·格拉维尔的片段......
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
};
}
}
我希望这最终能得到我想要的东西,但在以下代码中出现编译时错误,因为 Get Candidates() 无法将 CandidateS 隐式转换为 Candidate Base:
protected override IQueryable<CandidateBase> GetCandidatesCore()
{
return GetCandidates();
}
所以我添加了一个演员:
protected override IQueryable<CandidateBase> GetCandidatesCore()
{
return ((IQueryable<CandidateBase>)GetCandidates());
}
然后一切都会编译,但是当我实际在控制器中调用 GetCandidates() 时,它会返回IQueryable<CandidateBase>
代替IQueryable<CandidateA>
。所以我又回到了起点。
如果你能成功完成这一切并且可以帮助我,我将寄给你一瓶你最喜欢的 12 瓶啤酒!