抽象メソッドとリターンタイプの共分散について2日間のビートダウンを締めくくろうとしています。すでに、2つの同様の質問を投稿しており、提供された情報についてコミュニティに永遠に感謝しています。フィニッシュライン。これが私がやろうとしていることです。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で次の質問に出くわしました
C#のサブクラスのオーバーライドされたメソッドでサブタイプを返す方法は?
最終的に、私が探していたのは、リターンタイプに共分散を実装する方法であることに気づきました。MarcGravellのスニペットを使用しました...
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パックを送ります!