ジェネリックと継承にいくつかの問題があります。私はCriteriaBase
という抽象クラスを持っています。その仕事は、サブクラスで定義された基準T
と一致するかどうかを判断することです。サブクラスは、基準を表すFunc
を返すメソッドを実装する必要があります。問題は、Func
のジェネリックを使用しようとするときに発生します。うまくいけば、いくつかのコードは私の問題を説明します。'型引数は使用法から推論できません'
public abstract class CriteriaBase<T, U>
where T : ICrossoverable
where U : IChromosome
{
protected abstract Func<U, bool> Criteria { get; }
//some code removed for brevity
private int GetNumberOfCriteriaMatches(T season)
{
//1. works
//Func<IChromosome, bool> predicate = c => c.Genes == null;
//return season.Chromosomes.Count(predicate);
//2. doesn't work - The type arguments for method 'int
//System.Linq.Enumerable.Count<TSource>(this IEnumerable<TSource>,
//Func<TSource, bool>)'
//cannot be inferred from the usage. Try specifying the type arguments
//explicitly.
return season.Chromosomes.Count(Criteria);
}
}
私の意図はCriteriaBase
クラスは、一般的な、完全に再利用可能でなければならないことです。
例えばサブクラス:
public class TopTeamsPlayingEachOtherCriteria : CriteriaBase<Season, MatchDay>
{
//some code removed for brevity
protected override Func<MatchDay, bool> Criteria
{
get { return matchDay =>
matchDay.Fixtures.Count(
fixture =>
fixture.HomeTeam.TableGrouping.Ordering == 1
&& fixture.AwayTeam.TableGrouping.Ordering == 1) > 1; }
}
}
問題がGetNumberOfCriteriaMatches()
方法です。オプション2は私が最初にコードを書いたものですが、リストされているようにコンパイルエラーが発生します。オプション1を使用するとコードがコンパイルされますが、サブクラスでCriteria
をオーバーライドすると、MatchDay
の代わりにIChromosome
を使用する必要があります(MatchDay
の特定の機能にアクセスする必要があります)。私の単純な考え方では、オプション1と2は同等です。オプション2は、IChromosome
を、IChromosome
を実装するクラスに制限された汎用タイプU
に置き換えるだけです。
達成しようとしていることはありますか?もしそうなら、私は何か不足している/誤解ですか?もしそうでなければ、私はこの問題にどのように接近すべきですか?ここでは完全を期すために
は(私はそれが質問に役立ちますどのくらいかわからないとして末尾に含まれている)、私は現在T
(Season
)とU
のために使用しています2つのエンティティ(MatchDay
)です。
public class Season : ICrossoverable
{
private readonly IEnumerable<MatchDay> _matchDays;
public Season(IEnumerable<MatchDay> matchDays)
{
_matchDays = matchDays;
}
public IEnumerable<MatchDay> MatchDays
{
get { return _matchDays; }
}
//ICrossoverable implementation
public IEnumerable<IChromosome> Chromosomes
{
get { return _matchDays; }
}
}
public class MatchDay : IChromosome
{
private readonly int _week;
private readonly List<Fixture> _fixtures;
public MatchDay(int week, List<Fixture> fixtures)
{
_week = week;
_fixtures = fixtures;
}
//some code removed for brevity
public IEnumerable<Fixture> Fixtures
{
get { return _fixtures; }
}
//IChromosome implementation
public IEnumerable<IGene> Genes
{
get { return Fixtures; }
}
}
のバージョンネットフレームワークを使用していますか? –
.NETバージョン4 - クライアントプロファイルではないフルバージョン。バージョンによって回答は異なりますか?興味深い場合はVisual Studio 2010を使用してください。 – Stu
delegateの共分散とcontravarianceはバージョン4.0からのC#で動作しています –