はい、アブストラクトに関する質問をするのはこれで 4 日目です。申し訳ありませんが、SQLServer に関するいくつかの質問に答えて、コミュニティに恩返しをしようと思います。ともかく...
Linq クエリの結果を抽象基本クラス コレクションに射影するにはどうすればよいですか? これは、私の RecruiterBase 抽象クラスからのメソッドです (対応する CandidateBase 抽象クラスもあります)。
public IQueryable<CandidateBase> GetCandidates()
{
return from candidates in db.Candidates
where candidates.RecruiterId == this.RecruiterId
select candidates;
}
上記のメソッドは、Candidate と CandidateBase の間で暗黙的な変換を行うことができないというコンパイル時エラーをスローします。
db.Candidates を db.Candidates.Cast() に変更すると、すべてがコンパイルされますが、型 Candidate と CandidateBase の間に強制演算子が定義されていないというランタイム エラーが発生します。
できません: 抽象を実装できないため、CandidateBase として New CandidateBase { ... } を選択します。
Candidate と Candidate ベースの間に明示的な変換演算子を作成することもできません。
また、匿名型と CandidateBase 型の間で同じランタイム強制例外が発生するため、結果を匿名オブジェクトに投影してから CandidateBase にキャストすることもできません。
この問題は、昨日の質問、 抽象メソッドからの共変の戻り値に関する問題から生じました。
スタン R の答えは、私が物事を複雑にしているというものでした。私は戻って、すべてを単純化し(実装をベースに残し、サブから削除しました)、そのように実装された動作する GetCanidates メソッドになりました:
public IQueryable<CandidateBase> GetCandidates()
{
return (from candidates in db.Candidates
where candidates.RecruiterId == this.RecruiterId
select new CandidateA
{
CandidateId = candidates.CandidateId,
LastName = candidates.LastName,
RecruiterId = candidates.RecruiterId
}).Cast<CandidateBase>();
}
上記のメソッドはコンパイルして機能します。私は口の中で贈り物の馬を見ようとはしていませんが、現在、ベースタイプのサブタイプへの参照を持っています (結果を CandidateA に射影するとき)、それは奇妙に思えます。基本タイプ内からのサブタイプへの参照が問題ない場合は、私の質問に投票してください。
ありがとう。
完全なクラス定義:
public abstract class RecruiterBase
{
public int RecruiterId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public RecruiterBase()
{
}
public RecruiterBase(int id)
{
DataClasses1DataContext db = new DataClasses1DataContext();
Recruiter rc = db.Recruiters.SingleOrDefault(r => r.RecruiterId == id);
this.RecruiterId = rc.RecruiterId;
this.FirstName = rc.FirstName;
this.LastName = rc.LastName;
}
public IQueryable<CandidateBase> GetCandidates()
{
DataClasses1DataContext db = new DataClasses1DataContext();
return (from candidates in db.Candidates
where candidates.RecruiterId == this.RecruiterId
select new CandidateA
{
CandidateId = candidates.CandidateId,
LastName = candidates.LastName,
FirstName = candidates.FirstName,
RecruiterId = candidates.RecruiterId
}
).Cast<CandidateBase>();
}
}
public abstract class TempCandidateBase
{
public int CandidateId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int? RecruiterId { get; set; }
public CandidateBase()
{
}
public CandidateBase(int id)
{
DataClasses1DataContext db = new DataClasses1DataContext();
Candidate candidate = db.Candidates.SingleOrDefault(c => c.CandidateId == id);
this.CandidateId = candidate.CandidateId;
this.FirstName = candidate.FirstName;
this.LastName = candidate.LastName;
this.RecruiterId = candidate.RecruiterId;
}
}
public class RecruiterA : RecruiterBase
{
public RecruiterA()
: base()
{
}
public RecruiterA(int id)
: base(id)
{
}
}
public class CandidateA : CandidateBase
{
public CandidateA()
: base()
{
}
public CandidateA(int id)
: base(id)
{
}
}