我在泛型和继承方面遇到了一些麻烦。我有一个抽象类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
在子类中覆盖时,我必须使用IChromosome
而不是使用MatchDay
哪个不起作用(我需要访问 a 的特定功能MatchDay
)。在我看来,选项 1 和 2 是等效的。选项 2 简单地替换为仅限于实现的类IChromosome
的泛型类型。U
IChromosome
我想要实现的目标是可能的吗?如果是这样,我错过了什么/误解了什么?如果没有,我应该如何解决这个问题?
为了完整性(包括在最后,因为我不确定它对这个问题有多大帮助),这是我目前用于T
( Season
) 和U
( 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; }
}
}