我在使用泛型和遗传方面遇到了一些麻烦。我有一个名为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
这不起作用(我需要访问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; }
}
}
答案 0 :(得分:8)
这就是问题所在:
public IEnumerable<IChromosome> Chromosomes
您仅声明您正在返回一系列IChromosome
值。您的标准需要MatchDay
个值。 你碰巧知道它实际上返回了一系列MatchDay
值,但编译器没有。
您可以在执行时使用Cast<>
进行检查:
return season.Chromosomes.Cast<U>().Count(Criteria);
...或者您可以更改Chromosomes
以返回IEnumerable<MatchDay>
。不幸的是,我们无法确定这是否是一个有效的答案,因为我们不知道如何声明ICrossoverable
。也许你应该在元素类型中使ICrossoverable
泛型?
答案 1 :(得分:3)
您应该在CriteriaBase定义中使用U之前的关键字in
。像这样:
public abstract class CriteriaBase<T, in U>
where T : ICrossoverable
where U : IChromosome
<强>更新即可。不起作用。 尝试明确指定类型
private int GetNumberOfCriteriaMatches(T season)
{
....
return season.Chromosomes.Count<IChromosome>(Criteria);
}