来自抽象方法的协变量返回类型问题 [英] Problem with Covariant return types from an abstract method

查看:95
本文介绍了来自抽象方法的协变量返回类型问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图结束为期两天的抽象方法和返回类型协方差的分析,我已经发布了两个类似的问题,并且我非常感谢社区提供的信息,我只需要最后一推到达终点线。这是我想要做的事情:2个抽象类RecruiterBase和CandidateBase都具有RecruiterA和CandidateA的concreate实现。 RecruiterBase有一个抽象方法来获取所有返回IQueryable的应征候选人。我对RecruiterA的实现重写了GetCandidates()方法以返回IQueryable。

I’m trying to wrap up a two day beat down on Abstract methods and return type Covariance, I’ve already posted two similar questions and I am eternally grateful to the community for the info provided, I just need one last push to get to the finish line. Here is what I am trying to do: 2 abstract classes, RecruiterBase and CandidateBase, both have concreate implementations of RecruiterA and CandidateA. RecruiterBase has an abstract method to get all recruited candidates returning IQueryable. My implementation of RecruiterA overrides the GetCandidates() method to return 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 >。

Attempting to complile that throw a compile time error because in my implementation of RecruitreBase the GetCandidates() method returns IQueryable<CandidateA> instead of IQueryable<CandidateBase>.

无法从上一个问题获得建议之后()开始工作,我做了很多阅读,然后在SO中遇到了以下问题

After not being able to get the suggestions from a previous question (Generic return types from abstract/virtual methods) to work, I did a LOT more reading, and came across the following question in SO

如何以重写方法返回子类型

这最终使我意识到我一直在寻找的是对返回类型实现协方差的一种方法。我使用了马克·格雷夫(Marc Gravell)的代码段...

Which finally made me realize what I had been searching for was a way to implement Covariance for my return type. I used Marc Gravell's snippet...

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类看起来像:

... as the basis for my solution. So now my RecruiterBase and RecruiterA classes look like:

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:

I was hoping that would finally get me what I was looking for but I got a compile time error in the following code because GetCandidates() cannot implicitly convert CandidateA to CandidateBase:

  protected override IQueryable<CandidateBase> GetCandidatesCore()
  {
    return GetCandidates();
  }

所以我添加了演员表:

  protected override IQueryable<CandidateBase> GetCandidatesCore()
  {
    return ((IQueryable<CandidateBase>)GetCandidates());
  }

所有内容都会编译,但是当我在控制器中实际调用GetCandidates()时,它将返回 IQueryable< CandidateBase> 而不是 IQueryable< CandidateA> 。所以我就回到了我开始的地方。

Everything then compiles but when I actually call GetCandidates() in my controller it returns IQueryable<CandidateBase> instead of IQueryable<CandidateA>. So I am right back where I started.

如果您一直做到这一点,并且可以帮助我,我会给您12包您最喜欢的啤酒!

If you made it all the way through this and you can help me I'll send you a 12 pack of your favorite beer!

推荐答案

贾斯汀我有点困惑为什么你需要经历所有麻烦。

Justin I am a little bit confused why you need to go through all that trouble.

如果您的抽象方法的返回类型为 IQueryable< CandidateBase> ,那么您将得到。我认为这没有问题,因为以后您仍然可以将其回退到 CandidateA CandidateB

If you abstract method is of return type IQueryable<CandidateBase> then that's what you'll get. I don't see a problem with this, since later on you could still cast it back to CandidateA or CandidateB

那么您到底想实现什么?也许我不明白您的问题。

So what exactly are you trying to achieve? Maybe I am not understanding you question.

编辑添加:

Justin ,这是什么?

Justin, what about this?

public abstract class RecruiterBase<T>
    {
        // Constructors declared here

        public abstract IQueryable<CandidateBase> GetCandidates();
    }

    public abstract class CandidateBase
    {
        // Constructors declared here
    }


    public class CandidateA : CandidateBase
    {

    }

    public class RecruiterA : RecruiterBase<RecruiterA>
    {
        // Constructors declared here

        // ----HERE IS WHERE I AM BREAKING DOWN----
        public override IQueryable<CandidateBase> GetCandidates()
        {
            return db.Candidates.Where(cand => cand.RecruiterId == this.RecruiterId)
                         .Select(x => new CandidateA
                                          {
                                             CandidateId = c.CandidateId,
                                             CandidateName = c.CandidateName,
                                             RecruiterId = c.RecruiterId
                                           })
                         .Cast<CandidateBase>()
                         .AsQueryable();
        }
    }

这篇关于来自抽象方法的协变量返回类型问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆